本文為大地瓜原創,歡迎知識共享,轉載請注明出處。
雖然你不注明出處我也沒什么精力和你計較。
作者微信號:christgreenlaw
如果只有方法的實現而沒有聲明,那么類外部無法直接調用此方法。該方法就成為了表面上的私有方法。但是,OC中沒有真正的私有方法,因為OC采用的是消息機制。
{}形式的實例變量(成員變量)可以在@interface
中定義,也可以在@implementation
中定義。而在@implementation
中定義的變量和用@private
修飾的變量又不太一樣,在@implementation
中定義的變量只能在本類中訪問,其它類無法查看。
@property
是一個編譯器指令。
@synthesize
是一個編譯器指令, 它可以簡化我們getter/setter方法的實現。
在@synthesize后面告訴編譯器,將要使用的property叫什么,對應的實例變量叫什么。例子如下:
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
//@synthesize age = _age;
- (void)setAge:(int)age
{
_number = age;
}
- (int)age
{
return _number;
}
//@synthesize age = _number;
如果在@synthesize后面沒有告訴系統將傳入的值賦值給誰, 系統默認會賦值給和@synthesize后面寫得名稱相同的成員變量(Xcode4.4之前這個才有意義,目前的@property實現默認就是這樣)
@synthesize age;
- (void)setAge:(int)age
{
_age = age;
}
- (int)age
{
return _age;
}
在目前的實現中,當@property聲明了一個變量,默認就會使用對應的下劃線開頭的實例變量(這個實例變量就不必用花括號的形式寫出了)。但需要注意的是:它只會生成最簡單的getter/setter,不會對其進行其他操作。若需要對數據進行處理,則需要我們自己重寫getter/setter。
注意!!!!如果你同時重寫了getter和setter,那么@property將不會為你生成下劃線開頭的實例變量!!!你需要手動在花括號中聲明實例變量!!!
property修飾符
@property(readwrite) int age;
@property(getter=myName) NSString* name;
@property(setter=giveName:) NSString* name;
@property(getter=myName,setter=giveName:) NSString* name;
@property(readonly) NSString* id;
@property(getter=isMarried) NSString* married;
//能用修飾符處理的getter/setter就盡量不要額外去寫了,統一用修飾符處理
id
id是一個動態數據類型,可以用來:
- 定義變量
- 作為函數參數類型
- 作為函數返回值類型
一般情況下,所有的數據類型都是靜態數據類型,也就是說:
- 編譯時就知道是什么類型
- 知道類型有哪些方法和屬性
- 編譯時就可以確定的訪問類型的方法和屬性
- 若通過靜態類型定義變量,那么訪問不屬于靜態類型的方法或屬性,編譯器會報錯,無法通過編譯
作為動態類型:
- 編譯時不知道真是的類型,運行時才知道它的真實類型
- 通過動態數據類型定義變量,如果訪問不屬于動態數據類型的方法或屬性,編譯時不會報錯
一句話總結:動態數據類型,編譯器不知道你的真實類型,靜態類型反之
- 通過靜態數據類型定義變量, 不能調用子類特有的方法
- 通過動態數據類型定義變量, 可以調用子類特有的方法
- 通過動態數據類型定義的變量, 可以調用私有方法
為了避免動態數據類型調用不屬于自己的方法而引發的運行時錯誤,一般在使用前進行判斷,是不是能夠調用某方法:
if ([obj isKindOfClass:[Student class]]) {
// isKindOfClass , 判斷指定的對象是否是某一個類, 或者是某一個類的子類
[obj eat];
}
if ([obj isMemberOfClass:[Student class]]) {
// isMemberOfClass : 判斷指定的對象是否是當前指定的類的實例
[obj eat];
}
new方法其實就是alloc + init
默認情況下init(NSObject)什么都沒有做
alloc則初始化了isa實例變量,使其指向了自己所在的類,其他所有實例變量的值都設為0
由于歷史原因,alloc會觸發allocWithZone:
以上引用內容來自蘋果文檔。