@property本質(zhì)
@property = ivar + getter + setter
屬性(property) 有兩大概念:ivar(實例變量)、setter/getter(存取方法)
在定義屬性后,編譯器會自動生成一套存取方法,用以訪問給定類型中具有給定名稱的變量,所以
@property = getter + setter
@property 自動合成(autosynthesis)
如果使用了屬性的話,那么編譯器就會自動編寫訪問屬性所需的方法,此過程叫做“自動合成”( auto synthesis),使用時直接通過"self.property"的方式使用。所以一下兩組代碼是等同的
@interface JWUser : NSObject
@property (nonatomic, readwrite, copy) NSString *name;
@end
@interface JWUser : NSObject
- (void)setName:(NSString *)name;
- (NSString *)name;
@end
自動合成除了生成訪問方法外,還會向類中添加適當類型的實例變量,并在屬性名前加下劃線,以此作為實例變量的名字。
在上例中,會生成一個實例變量,名稱為:_name。我們也可以在.m中通過@synthesize語法來指定實例變量名字:
@implementation JWUser
@synthesize name = _name;
@end
上述語法將生成的實例變量名字改為:_name,而不再使用默認的名字。我們可以通過@synthesize語法將實例變量名稱修改成我們想要的,比如
@synthesize name = userName;
但一般不建議這么做,因為不符合默認的書寫規(guī)范,正常建議還是使用默認命名方案。
自動合成大致的實現(xiàn)原理
OBJC_IVAR_$類名$屬性名稱 :該屬性的“偏移量” (offset),這個偏移量是“硬編碼” (hardcode),表示該變量距離存放對象的內(nèi)存區(qū)域的起始地址有多遠。
setter 與 getter 方法對應的實現(xiàn)函數(shù)
ivar_list :成員變量列表
method_list :方法列表
prop_list :屬性列表
也就是說我們每次在增加一個屬性,系統(tǒng)都會在 ivar_list 中添加一個成員變量的描述,在 method_list 中增加 setter 與 getter 方法的描述,在屬性列表中增加一個屬性的描述,然后計算該屬性在對象中的偏移量,然后給出 setter 與 getter 方法對應的實現(xiàn),在 setter 方法中從偏移量的位置開始賦值,在 getter 方法中從偏移量開始取值,為了能夠讀取正確字節(jié)數(shù),系統(tǒng)對象偏移量的指針類型進行了類型強轉(zhuǎn).
autosynthesize合成實例變量規(guī)則:
- 如果指定了成員變量名稱(
@synthesize),會生成一個指定的名稱的成員變量;
- 如果這個成員已經(jīng)存在就不再生成了;
- 如果@synthesize foo;會生產(chǎn)一個名稱為foo的成員變量;
- 如果屬性名為foo,并且存在名為_foo的成員變量,那么不會合成新的成員變量,參考如下代碼;
@property (nonatomic, readwrite, copy) NSArray *array;
@property (nonatomic, readwrite, copy) NSArray *_array;
此時會在 _array處提出警告auto property synthesize will not synthesize property '_object' because it cannot share an ivar with another synthesized property
@property中有哪些屬性關(guān)鍵字?/ @property 后面可以有哪些修飾符?
- 原子性 --- nonatomic, atomic
- 讀/寫權(quán)限--- readwrite(讀寫) readonly(只讀)
- 內(nèi)存--- assign、weak、string、copy、unsafe_unretained
- setter/getter方法名 getter=<函數(shù)名> setter=<函數(shù)名>
- 其它:nonnull,null_resettable,nullable
- ARC模式下,如果不指定任何關(guān)鍵字,默認關(guān)鍵字包括
基本數(shù)據(jù)類型
atomic,readwrite,assign
普通Objective-C對象類型
atomic,readwrite,strong