一基括、setter和getter的一般寫法
setter和getter器可以說是一個(gè)類最基本的東西颜懊,任何一門面向?qū)ο?/code>的語言,都又這個(gè)概念风皿,C++河爹、java等等。因?yàn)閟etter和getter是對面向?qū)ο笳Z言封裝的最基本的支持桐款。
在Objective-C的setter和getter器咸这,當(dāng)然也和一般的語言沒有什么不同。只不過魔眨,添加了一些自己的特性媳维。
比如有一個(gè)實(shí)例變量:int age;
先在.h文件中聲明setter和getter器
然后在.m文件中具體實(shí)現(xiàn)
可以看出來,在Objective-C中setter器沒什么區(qū)別冰沙,不過getter器的方法名缺少了get侨艾,因?yàn)間et...在Objective-C有別的用處,所以getter器直接寫的就是變量名拓挥。
二唠梨、調(diào)用getter和setter方法
- 一般的調(diào)用方法,是傳統(tǒng)的帶中括號[]的調(diào)用方法
- 點(diǎn)調(diào)用的方式
oc語法關(guān)于點(diǎn)表達(dá)式的說明:"點(diǎn)表達(dá)式(.)看起來與C語言中的結(jié)構(gòu)體訪問以及Java語言匯總的對象訪問有點(diǎn)類似侥啤,其實(shí)這是oc的設(shè)計(jì)人員有意為之当叭。如果點(diǎn)表達(dá)式出現(xiàn)在等號左邊,該屬性名稱的setter方法將被調(diào)用盖灸。如果點(diǎn)表達(dá)式出現(xiàn)在右邊蚁鳖,該屬性名稱的getter方法將被調(diào)用。"
三赁炎、引入屬性@property改進(jìn)setter和getter
每次要為一個(gè)屬性寫上getter和setter醉箕,不得不十分麻煩,所以蘋果公司為OC引入了@property,用來改進(jìn)setter和getter
- 在ios第一版中讥裤,我們?yōu)檩敵隹谕瑫r(shí)聲明了屬性和底層實(shí)例變量放棒,那時(shí),屬性是oc語言的一個(gè)新的機(jī)制己英,并且要求你必須聲明與之對應(yīng)的實(shí)例變量间螟,例如:
.h
.m
- 在Xcode中間的一個(gè)版本中,不再需要為屬性聲明實(shí)例變量了损肛,因?yàn)锧synthesize默認(rèn)會去訪問str的同名厢破,如果找不到同名變量,會自動生成一個(gè)叫做str的私有同名變量治拿。
.h
.m
- 在xcode4.5及以后的版本中摩泪,直接把@synthesize給省略
.h
編譯器會自動為你生成setter和getter方法 和 以下劃線開頭的實(shí)例變量_str,不需要自己手動再去寫實(shí)例變量忍啤。
在這里說明一下@synthesize的作用
1加勤、一個(gè)作用就是讓編譯器為你自動生成setter與getter方法。
2同波、還有一個(gè)作用,可以指定與屬性對應(yīng)的實(shí)例變量叠国,例如@synthesize str = xxx;
那么操作的實(shí)例變量是xxx未檩,而不是_str了。如果.m文件中寫了@synthesize str;
那么生成的實(shí)例變量就是str粟焊;如果沒寫@synthesize str;那么生成的實(shí)例變量就是_str冤狡。(注意:_str這個(gè)實(shí)例變量是不存在的). 在老式的代碼中,@property只能寫在@interface @end
中项棠,@synthesize只能寫在@implementation @end
中悲雳,自從xcode 4.5及以后的版本中,@property就獨(dú)攬了@property和@synthesize的功能香追。
@property (nonatomic, copy) NSString *str;
這句話完成了3個(gè)功能:
1)生成_str成員變量的getter和setter方法的聲明合瓢;
2)生成_str成員變量setter和getter方法的實(shí)現(xiàn);
3)生成一個(gè)_str的成員變量透典。(注意:這種方式生成的成員變量是private的)
四晴楔、對屬性的一些設(shè)置
1、設(shè)置訪問方法的名字
默認(rèn)的getter和setter器的名稱是和變量名關(guān)聯(lián)的峭咒,一定是setVirableName和virableName税弃,比如上面的變量age,setter是setAge凑队,getter是age则果。可以通過設(shè)置@property中的setter和getter屬性來修改setter和getter器的方法名。
- getter=getterName
- setter=setterName
舉個(gè)例子:
注意:如果你設(shè)置了readonly屬性的話西壮,那么你就不應(yīng)該設(shè)置setter屬性导匣,要不然會給出一個(gè)編譯器的警告。
2茸时、設(shè)置只讀或讀寫
readwrite:表示既有g(shù)etter贡定,也有setter
readonly:表示只有g(shù)etter,沒有setter
這兩個(gè)屬性是互相排斥的可都,只能存在一個(gè)缓待。
五果正、屬性重寫setter和getter方法
使用屬性@property能夠幫我們省去了很多繁雜的工作砌们,但有的時(shí)候我們在使用屬性的時(shí)候還是需要去重寫一下其setter和getter方法份帐,這個(gè)時(shí)候我們應(yīng)該怎么做呢
- 如果只重寫setter和getter其中之一雾鬼,可以直接重寫
- 如果同時(shí)重寫setter和getter祈餐,需要加上
@synthesize propertyName = _propertyName;
不然系統(tǒng)會不認(rèn)_str产园。因?yàn)槿绻阃瑫r(shí)重寫了getter和setter方法坯约,系統(tǒng)就不會幫你自動生成這個(gè)_str變量盖溺,所以當(dāng)然報(bào)錯(cuò)說不認(rèn)識這個(gè)變量答姥。所以得手動指定成員變量铣除,然后再同時(shí)重寫了getter和setter方法。
注意事項(xiàng):
在重寫set和get時(shí)鹦付,容易犯如下錯(cuò)誤尚粘,會造成死循環(huán)。
1敲长、在set方法中郎嫁,self.age=age;相當(dāng)于是[self setAge:age];
2、在get方法中祈噪,return self.age;相當(dāng)于是[self age];
以下情況下泽铛,都不會autosynthesis(自動合成):
1、同時(shí)重寫setter和getter時(shí)
2辑鲤、重寫了只讀屬性的getter時(shí)
3盔腔、使用了@dynamic時(shí)
4、在@protocol中定義的所有屬性
5遂填、在Category中定義的所有屬性
6铲觉、重載的屬性