OC中的屬性Property和點(diǎn)語法
屬性是什么
我們都知道,屬性是變量和它對(duì)應(yīng)的setter和getter方法的集合瘩将,是一種語法糖凯傲,是一種簡(jiǎn)化的寫法。也就是說磕诊,當(dāng)你聲明了一個(gè)屬性的時(shí)候填物,你同時(shí)聲明了一個(gè)變量,一個(gè)setter方法霎终,一個(gè)getter方法滞磺。
@property NSObject *property;
等價(jià)于
NSObject *_property;
- (void)setProperty:(NSObject *)property {
_property = property;
}
- (NSObject *)property {
return _property;
}
這次我們就來了解一下OC中屬性的一些特性。
對(duì)比Swift中的屬性類型
在Swift中莱褒,屬性是有很多類型的击困,有存儲(chǔ)屬性、計(jì)算屬性广凸、延遲屬性阅茶、可選屬性、類屬性等谅海。
Swift是以O(shè)C為基礎(chǔ)而設(shè)計(jì)的全新語言目派,它雖然有著全新的更全面的語法特性,但是依然能看出OC的影子胁赢。相反的企蹭,我們可以從Swift的對(duì)比中分析OC的一些特性白筹。
存儲(chǔ)屬性
現(xiàn)在,我們聲明一個(gè)字符串屬性:
@property NSString *str;
這其實(shí)就是一個(gè)存儲(chǔ)屬性谅摄,因?yàn)樗闪艘粋€(gè)變量用來存放字符串?dāng)?shù)據(jù)徒河。
計(jì)算屬性
那計(jì)算屬性又是什么呢?
計(jì)算屬性不直接存儲(chǔ)值送漠,而是提供一個(gè) getter 來獲取值顽照,一個(gè)可選的 setter 來間接設(shè)置其他屬性或變量的值。
根據(jù)上面的描述得出:就是沒有生成變量闽寡,只有setter/getter方法的屬性就是計(jì)算屬性代兵。其實(shí)在很早之前,定義屬性的時(shí)候是不會(huì)生成變量的爷狈,需要使用 @synthesize str = _str;
這樣的方式來生成變量植影,同時(shí)定義變量的名稱。但在后來涎永,Apple默認(rèn)會(huì)生成變量思币。
那么在OC中,如何創(chuàng)建一個(gè)計(jì)算屬性呢羡微?
在OC中谷饿,有這樣一條規(guī)則,如果聲明的屬性同時(shí)重寫了setter方法和getter方法妈倔,需要使用 @synthesize
重新聲明變量博投。也就是說,如果不聲明變量盯蝴,他就是一個(gè)有著setter/getter方法的計(jì)算屬性毅哗。
那么如果只需要實(shí)現(xiàn)setter/getter方法中的其中一個(gè)的計(jì)算屬性怎么辦呢?這里就到了@dynamic
關(guān)鍵字登場(chǎng)了结洼。
被@dynamic`修飾的屬性在OC中被稱為動(dòng)態(tài)屬性黎做。顧名思義,就是用于動(dòng)態(tài)計(jì)算的屬性松忍。
@synthesize
和@dynamic
都是定義在@implementation
下面的蒸殿。
延遲屬性
Swift中的延遲屬性,在OC中的表現(xiàn)形式就是懶加載鸣峭。
- (NSMutableArray *)dataSource {
if (!_dataSource) {
_dataSource = [[NSMutableArray alloc] init];
}
return _dataSource;
}
這是一個(gè)典型的懶加載模式宏所,是通過重寫getter方法來動(dòng)態(tài)的初始化變量,但是這樣的寫法并不完全滿足延遲屬性摊溶,因?yàn)樵摲椒ㄒ呀?jīng)無法獲取到nil
這個(gè)值了爬骤。
可選屬性
在Swift中,每個(gè)對(duì)象初始化的時(shí)候莫换,所有的存儲(chǔ)屬性必須得到初始化霞玄,為了簡(jiǎn)化類的初始化骤铃,所以增添了可選型Optional】谰纾可選屬性默認(rèn)值為nil
惰爬。在OC中,所有定義的屬性并沒有強(qiáng)制初始化惫企,所以都為可選屬性撕瞧。
類屬性
類屬性,顧名思義就是類自身的屬性狞尔,他不屬于對(duì)象丛版,而是屬于類本身。通過class
修飾符實(shí)現(xiàn)偏序。
@property (class, readonly, strong) NSUserDefaults *standardUserDefaults;
@property (class, readonly, strong) NSFileManager *defaultManager;
@property (class, readonly, strong) NSNotificationCenter *defaultCenter;
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) UIPasteboard *generalPasteboard;
#else
+ (UIPasteboard *)generalPasteboard;
#endif
如今iOS框架中的單例方法都從一個(gè)單例方法逐步變成了現(xiàn)在的類屬性的方式页畦。
定義的類屬性需要使用
@dynamic
修飾
點(diǎn)語法
點(diǎn)語法是跟隨屬性的應(yīng)用而生的,是為了更加簡(jiǎn)單方便的訪問屬性而出的語法特性禽车。而他本質(zhì)上其實(shí)是一個(gè)動(dòng)態(tài)方法寇漫,它無關(guān)乎是否是屬性刊殉,它只是轉(zhuǎn)換成對(duì)應(yīng)setter/getter方法格式的參數(shù)來調(diào)用方法而已殉摔。
如下兩個(gè)方法也可以使用點(diǎn)語法來調(diào)用,就是這個(gè)道理记焊。
- (id)copy;
- (id)mutableCopy;