- 定義類:
@interface 類名 : 父類
@end
- 使用:(冒號)表示繼承一個類
Student : NSObject
- 使用()定義一個Catagory(類別)
- 作用:在不改變原有類結(jié)構(gòu)的基礎(chǔ)上执泰,擴展原有類的方法(不能擴展屬性)阔挠,但不建議重載原有類的方法
- 開發(fā)工具默認(rèn)生成的文件為:類名+Catagory名稱
- Catagory可以寫在單獨的文件中撵摆,也可以寫在原有類的文件中册着,如何寫根據(jù)需求來決定览露。
- 使用<>表示實現(xiàn)一個Protocol(協(xié)議),如需實現(xiàn)多個協(xié)議,將協(xié)議名以逗號分隔都寫在括號中即可
*可以理解為java中的接口搞挣,但不同的是,實現(xiàn)類編譯器不強制實現(xiàn)Protocol中定義的所有接口
- 在方法簽名上標(biāo)識:@required,從字面上理解實現(xiàn)類必須實現(xiàn)該方法音羞,其實寫與不寫一樣的效果囱桨。也是默認(rèn)的
- 在方法簽名上標(biāo)識:@optional,表示實現(xiàn)類對該方法的實現(xiàn),是可選的嗅绰。
- 屬性的訪問權(quán)限
- private : 只有類內(nèi)部可以訪問
- protected : 類內(nèi)部和子類可以訪問(默認(rèn))
- public : 訪問沒有限制
例:
// 定義
@interface Student : NSObject {
@private int _age;
@protected int _no;
@public float _height;
}
@end
// 使用
Student *stu = [[[Student alloc]init]autorelease];
stu->_height = 20;// 直接讀寫屬性的值舍肠,開發(fā)當(dāng)中一般不建議這么做。違背了面向?qū)ο蟮拈_發(fā)原則-》封裝性
- 屬性的定義與封裝
// in Student.h
@interface Student : NSObject {
// 1. 定義屬性窘面,默認(rèn)訪問權(quán)限是@protected的翠语,只有自已和子類可以直接訪問
int _age;// OC語法中建議屬性名前面加上下劃線,以和參數(shù)名區(qū)分
int _no;
}
// 2.提供屬性對外讀寫方法的聲明财边,供外界調(diào)用肌括。OC創(chuàng)建屬性讀寫方法的命名規(guī)則是為,set方法: set+屬性名,get方法:屬性名
// 聲明age的get和set方法
- (int)age;
- (void)setAge:(int)age;
// 聲明no的get和set方法
- (int)no;
- (void)setNo:(int)no;
@end
// in Student.m 實現(xiàn)頭文件中的方法
#import "Student.h"http:// 導(dǎo)入頭文件
@implementation Student
// 實現(xiàn)頭文件中的方法
- (int)age { // age的getter方法
return _age;
}
- (void)setAge:(int)age {// age的setter方法
_age = age;
}
- (int)no {
return _no;
}
- (void)setNo:(int)no {
_no = no;
}
@end
- 使用@synthesize自動生成屬性getter和setter方法的實現(xiàn)酣难,同時會生成一個下劃線(_)+屬性名的成員變量谍夭。需要和@property配合使用。例:
@implementation Student
@synthesize age;// 這一句頂下面的get和set方法鲸鹦,由@synthesize自動生成
- (int)age { // age的getter方法
return _age;
}
- (void)setAge:(int)age {// age的setter方法
_age = age;
}
@end
注:在xcode4.5以后的編譯環(huán)境中慧库,不需要寫@synthesize聲明生成屬性的get和set方法實現(xiàn)。只需要在頭文件中用@property定義即可自動在.m文件中生成相應(yīng)屬性的get和set方法實現(xiàn)
- 使用@property聲明一個屬性,編譯器會自動生成該屬性的getter和setter方法的聲明
在xcode4.5以后版本的編譯器環(huán)境中馋嗜,會自動在.m文件中生成該屬性getter和setter方法的標(biāo)準(zhǔn)實現(xiàn)齐板,不需顯示聲明用@synthesize來生成屬性的getter和setter方法實現(xiàn)。
- @property屬性參數(shù)
1> nonatomic : 多線程環(huán)境下,不需要線程保護(讀寫時不加鎖),
atomic : (默認(rèn))多線程環(huán)境下需要線程保護(讀寫時加鎖).
2> readonly : 表示在.m文件中只生成屬性的getter方法的實現(xiàn)
readwriter : 表示在.m文件中生成屬性的getter和setter方法的實現(xiàn)(默認(rèn))
3> retain : 表示調(diào)用該屬性的setter方法時甘磨,先release舊的值橡羞,再retain新的值。一般聲明的成員變量是NSObject的子類才會添加該參數(shù)
assign : 生成標(biāo)準(zhǔn)的getter和setter方法實現(xiàn)(默認(rèn))济舆,直接給屬性賦值
4> getter= : 表示自定義屬性生成的getter方法名稱
setter= : 表示自定義屬性生成的setter方法名稱
- 方法調(diào)用
- [實例對象 方法名:參數(shù)列表]
- [類名 方法名:參數(shù)列表]
例:
Student *stu = [[[Student alloc]init]autorelease];
[stu setAge:22 andNo:10];// 調(diào)用實例方法
[Student initWithAge:20];// 調(diào)用靜態(tài)方法
- 點(.)語法
Student *stu = [[[Student alloc]init]autorelease];
stu.age = 20; // 相當(dāng)于調(diào)用了對象的setAge方法(寫)
int age = stu.age;// 相當(dāng)于調(diào)用了對象的getAge方法(讀)
- self關(guān)鍵字
相當(dāng)于java中的this卿泽,不同的是self在不同的環(huán)境下,作用也不同滋觉。在實例方法中self可以當(dāng)該對象使用签夭,在靜態(tài)方法中,self可以當(dāng)類對象使用椎侠。
如:
- (void)age {
return self.age;// 這里self是實例對象本身
}
+ (id)newInstace {
//Student *stu = [[[Student alloc]init]autorelease];
Student *stu = [[[self alloc]init]autorelease];// 這一句和上一句代碼的效果是等效的第租,而在java語法是不允許this出現(xiàn)在靜態(tài)方法中的
return stu;
}
- @class : 在頭文件中聲明一個類的存在
為了提高效率,在只需要知道類的存在的情況下我纪,不需要導(dǎo)入某個類的頭文件慎宾。
// #import "Book.h"
@class Book; // 不需要導(dǎo)入Book.h頭文件,在.m文件真正使用的時候再導(dǎo)入
@interface Student : NSObject
@property Book *book;
@end
@protocol : 在頭文件中聲明一個協(xié)議的存在
目的和@class一樣^ : 定義一個Block類型浅悉,與標(biāo)準(zhǔn)C語法中指向函數(shù)指針類型的寫法非常相似
如:定義一個sum的Block類型趟据,返回值為int,有兩個int形參
int (^sum) (int, int) = ^(int a, int b) {
return a + b;
};
-
import : 用于導(dǎo)入一個類的頭文件
#pragma mark : 寫方法的注釋
#pragma mark - : 方法注釋分組
+ : 聲明或定義一個靜態(tài)方法
- : 聲明或定義一個實例方法
- 方法定義(一個冒號代表一個參數(shù)术健,冒號也是屬性方法的一部份)
方法類型 (返回值類型)方法名稱[參數(shù)列表] {(一個冒號代表一個參數(shù)汹碱,冒號也是屬性方法的一部份)
// 方法體
}
// 實例方法,方法名: sumAge:andNo:
- (int)setAge:(int)age andNo:(int)no {
// 在這里插入代碼邏輯
}
// 靜態(tài)方法
+ (id)initWithAge:(int)age {
// 在這里插入代碼邏輯
}
注:
* 實例方法通過類的實例對象訪問
* 靜態(tài)方法通過類名或self訪問
- 內(nèi)存管理
1> 凡是從NSObject中繼承的類都需要自己管理內(nèi)存苛坚,在OC語法中比被,創(chuàng)建的任何一個對象都擁有一個引用計數(shù)器,第一次創(chuàng)建的時候這個引用計數(shù)器為1泼舱,當(dāng)引用計數(shù)器的值為0時等缀,該對象會被銷毀。內(nèi)存管理涉及到以下接口:
- release : 對象的引用計數(shù)器減1
- retain : 對象的引用計數(shù)器加1
- retainCount : 獲取對象當(dāng)前引用計數(shù)器的數(shù)量
對象生命周期回調(diào)接口: - init : 對象的默認(rèn)構(gòu)造方法娇昙,如果自定義構(gòu)造方法用于初始化成員變量時尺迂,必須先調(diào)用父類的構(gòu)造方法,并判斷獲得的對象是否為nil冒掌,再初始化成員變量噪裕。
如:
- (void)initWithAge:(int)age {
if ( self = [super init] ) {
_age = age;
}
return self;
}
- dealloc : 對象銷毀時,系統(tǒng)會自動調(diào)用該方法股毫,通常在該方法中釋放內(nèi)存或其它資源膳音。在重寫dealloc方法時,注意在代碼最后面調(diào)用父類的dealloc方法铃诬,用于釋放內(nèi)存等相關(guān)資源祭陷。
如:
- (void)dealloc {
[_book release];// 釋放成員變量
[super dealloc];
}
2> 不需要管理內(nèi)存的對象
- 基本數(shù)據(jù)類型
- 系統(tǒng)自帶的類調(diào)用自己的靜態(tài)方法創(chuàng)建的對象苍凛,是自動釋放內(nèi)存的,不需要管理
3> 內(nèi)存管理原則
只有向?qū)ο蟀l(fā)送了alloc,retain,copy,new消息才有必要做release操作
- 誰alloc,retain,copy,new誰release
- 誰創(chuàng)建誰釋放(release)
- 誰沒有allock,retain,copy,new兵志,你就不要做release操作
4> 自動內(nèi)存管理(由autoreleasepool管理)
在創(chuàng)建對象的同時醇蝴,調(diào)用autorelease方法,會將該對象的一個 引用自動存放到最近創(chuàng)建的一個自動釋放釋放池中想罕。以后該對象就不需要手動來release操作悠栓,徐非做了retain,copy等修改了引用計數(shù)器的操 作。當(dāng)自動釋放池被銷毀時按价,會向池子中所有對象發(fā)送一個release消息惭适,池子中的所有對象的引用計數(shù)器此時會減1,只有當(dāng)池子中的引用計數(shù)器為0時俘枫, 該對象才會被徹底銷毀腥沽。不是說只要將對象交給自動釋放池了,池子被銷毀鸠蚪,池子中的所有對象就一定會被銷毀。
如:
@autoreleasepool {
Student *stu = [[[Student alloc] init]autorelease];// 此時stu對象將放到這個大括號中的自動釋放池子中
[stu retain];
// 如果加了這一句师溅,此時stu的引用計數(shù)器為2茅信,這時候如果在池子銷毀前沒有向?qū)ο蟀l(fā)送release消息,就算池子銷毀墓臭,該對象也還是會造成內(nèi)存泄露
} // 程序執(zhí)行到此處蘸鲸,代表自動釋放池被銷毀,意味著池子中的所有對象都會接到一個release消息
- OC中的類似Java的toString方法
Student *stu = [[[Student alloc]init]autorelease];
NSLog(@"%@",stu);// 默認(rèn)打印的是stu對象的內(nèi)存地址
- 重寫父類的description方法窿锉,可自定義打印對象的信息
- (NSString *)description {
NSLog(@"age is %i",_age);
}