使用屬性編程:
一般來說,屬性指的是一個對象的屬性或特性克伊。對象的實例變量酥郭,也就是訪問方法的目標(biāo)一般被稱為屬性。
以前的接口文件中使用實例變量和訪問方法實現(xiàn)屬性的概念愿吹,而現(xiàn)在把屬性的概念作為一個獨立的存在在接口中聲明不从。
屬性聲明的規(guī)則總結(jié)如下:
自動生成訪問方法
自動生成實例變量
更簡單的調(diào)用訪問方法
屬性的內(nèi)省
屬性的概念:
使用屬性聲明,可以更簡潔地實現(xiàn)訪問方法犁跪。另一方面椿息,不僅僅是訪問方法,KVC中所有定義的實例變量都可以被當(dāng)作屬性處理坷衍。
顯式聲明屬性:
OC2.0中新增加了屬性聲明的功能寝优。這個功能可以讓編譯器自動生成與數(shù)據(jù)成員同名的方法。
@property int hitPoint枫耳;
屬性聲明等同于聲明了讀寫兩個訪問方法倡勇。
屬性聲明的時候還可以為屬性自定義選項。選項位于圓括號中嘉涌,前面是@property指令。例如如果想聲明一個只讀的訪問方法夸浅,可以在@property后面加上(readonly)仑最。
@property(readonly) ?NSString *name;
當(dāng)兩個屬性的類型相同時帆喇,既可以單獨寫一行警医,也可以將他們寫一起。例如:
@property int hitPoint, magicPoint预皇;
屬性的實現(xiàn):
通過使用@synthesize侈玄,就可以在一行之內(nèi)自動生成getter和setter方法。將語句應(yīng)放在@implementation和@end之間吟温,就能自動生成和接口文件中聲明的屬性一致的訪問方法(可讀可寫或只讀)序仙。也可以不使用@synthesize自動生成,而是由自己來實現(xiàn)訪問方法鲁豪。另外我們還可以通過@dynamic關(guān)鍵字告訴編譯器合成無效潘悼,用戶會自己生成getter和setter。
其他方法可以直接在實現(xiàn)文件中實現(xiàn)爬橡,而不用在接口文件中聲明治唤。但是屬性聲明的情況下則不允許這種做法。
使用@synthesize的時候糙申,可以在一行中聲明多個變量宾添。
通常情況下,@property聲明的屬性名稱和實例變量的名稱是相同的柜裸,但有時你也可能會需要屬性的名稱和實例變量的名稱不同缕陕,這時就可以為實例變量定義其他的屬性名稱。例如我們可以通過該語句生成名為value的訪問方法粘室,并將其綁定到實例變量runningAverage中:
@synthesize value = runningAverage榄檬;
可以在類的實現(xiàn)部分中聲明一部分或全部實例變量,這種聲明方法可以隱藏是否對變量進(jìn)行了屬性聲明衔统。另外在子類中訪問實例變量時也只能通過訪問方法來訪問鹿榜,不能直接訪問父類的實例變量。
通過屬性聲明的方法也能夠同訪問方法一樣實現(xiàn)封裝的目的锦爵。
給屬性指定選項:
可以同時給一個變量指定多個選項舱殿,選項之間需要用逗號隔開。
@property 可用選項:
種類
選項
說明
指定方法名
getter = getter方法名
setter = setter方法名顯式指定getter方法和setter方法的名字
讀寫屬性
readonly
readwrite只讀
讀寫
賦值時的選項
assign
retain
unsafe_unretained
strong
weak
copy單純賦值
進(jìn)行保持操作
同assign一樣(用于ARC)
同retain一樣(用于ARC)
弱引用(用于ARC)
復(fù)制對象
原子性操作
nonatomic
非原子性操作险掀,非線程安全
指定方法名:
可以不使用默認(rèn)的訪問方法名沪袭,而通過setter option來指定訪問屬性用的方法名。例:
@property(setter = setValue:)int hitPoint樟氢;
可以通過點運算符來調(diào)用 .hitPoint冈绊,但實際上啟動的方法是setValue:
讀寫屬性:
readwrite表示屬性是可讀寫的,這也是默認(rèn)選項埠啃。
賦值時的選項:
六個選項之間是排他關(guān)系死宣。unsafe_unretained和strong主要被用在ARC的情況下,分別和assign和retain具備同樣的功能碴开。
基礎(chǔ)數(shù)據(jù)類型
對象類型:手動引用計數(shù)
對象類型:ARC
對象類型:垃圾回收
未指定任何選項
直接賦值
警告
警告
直接賦值(有可能出現(xiàn)警告)
assign
unsafe_unretained直接賦值
直接賦值
直接賦值
直接賦值
retain
strong出錯
賦值并對新值進(jìn)行retain
賦值并對新值進(jìn)行retain
無特別操作毅该,和assign動作相同
weak
出錯
無特別操作博秫,和assign動作相同
弱引用
無特別操作,和assign動作相同
copy
出錯
賦值時建立傳入值的一份副本
賦值時建立傳入值的一份副本
賦值時建立傳入值的一份副本
屬性是對象類型眶掌,且使用了垃圾回收管理內(nèi)存挡育,有一點需要注意,對于符合NSCopying協(xié)議也就是說可以利用copy方法的類實例變量朴爬,如果不指定任何選項即寒,就會提示警告。
原子性:
原子性是多線程中的一個概念寝殴,如果說訪問方法是原子的蒿叠,那就意味著多線程環(huán)境下訪問屬性是安全的在執(zhí)行過程中不可被打斷。而nonatomic則正好相反蚣常,意味著方法在執(zhí)行時可被打斷市咽,缺省情況下訪問方法是原子的。
通常不需要指定nonatomic選項抵蚊,因為這樣的機(jī)制能提高訪問的安全性施绎。但畢竟lock和unlock操作對性能有影響,因此贞绳,對于使用頻繁且不用考慮多線程競爭的訪問方法可以在聲明的時候加上nonatomic谷醉。
nonatomic選項不僅能被用于使用@synthesize生成的訪問方法,手動定義的訪問方法中不存在多線程競爭的情況下冈闭,也可以給屬性加上nonatomic俱尼。
屬性聲明和繼承:
子類可以使用父類中定義的屬性,也可以重寫父類中定義的訪問方法萎攒,但是遇八,父類中屬性聲明時指定的各種屬性(assign等),或者為實例變量指定的getter和setter的名稱等必須完全一樣耍休。唯一一個特別的情況是刃永,對于父類中被定義為readonly類型的屬性,子類中可以將其變?yōu)閞eadwrite羊精。
屬性的聲明可能會包含范疇或協(xié)議斯够,這種情況下實現(xiàn)文件中不可以使用@synthesize,原因是范疇和協(xié)議都和實例變量的實現(xiàn)無關(guān)喧锦,需要在實現(xiàn)文件中實現(xiàn)訪問方法读规。
方法族和屬性的關(guān)系:
使用ARC的時候,必須注意方法的命名燃少,不要和方法族發(fā)生沖突掖桦。
點操作符的使用方法:
OC2.0會在編譯時把使用點操作符訪問屬性的過程理解為訪問方法的調(diào)用,因為調(diào)用的是訪問方法供汛,所以無論對應(yīng)的實例變量是否存在,只要訪問方法存在,就都可以通過點操作符訪問屬性怔昨。
點操作符只能用于類類型的實例變量雀久,不能對id類型的變量應(yīng)用點操作符。因為沒指定類型的情況下趁舀,編譯器無法判斷是否存在屬性對應(yīng)的訪問方法赖捌。
復(fù)雜點操作符的使用方法:
連用點操作符:
當(dāng)一個對象的實例變量是另外一個對象時,可用過連用點操作符來訪問對象的實例變量中的成員矮烹。如果連用表達(dá)式中有一個是nil越庇,則整個表達(dá)式的返回值就是nil。
連續(xù)賦值:
賦值時從右向左解釋奉狈。
對遞增卤唉,遞減和復(fù)合賦值運算符的解釋:
e = obj.depth++;
賦值表達(dá)式的右側(cè)連續(xù)調(diào)用了getter和setter方法,相當(dāng)于執(zhí)行了[ obj setDepth: [ obj depth ] + 1 ]仁期。最后為e賦值的是遞增操作之前的depth的值桑驱。
self使用點操作符:
類的方法中可以通過對self應(yīng)用點操作符來調(diào)用自己的訪問方法。但要注意的是跛蛋,不要在訪問方法中使用self熬的,否則會造成無限循環(huán)的遞歸,無法終止赊级。
super使用點操作符:
可以通過給super加點操作符來調(diào)用父類中定義的setter和getter方法押框。例如:
- (void)setDepth:(int
)val {
super
.depth = (val <= maxDepth) ? val : maxDepth;
}
和構(gòu)造體成員混用:
獲取類屬性的點操作符和訪問結(jié)構(gòu)體元素的點操作符可以混用。不能通過取地址符來對點操作符獲得的屬性取地址理逊。
當(dāng)給obj的實例變量contents發(fā)送消息時橡伞,你可能會這樣寫:[ obj.contents retain ] ?。但要注意的是挡鞍,實際上這行語句表示的是給getter方法的返回值發(fā)送了消息骑歹,并不一定會給obj的實例變量contents發(fā)送消息。
使用點操作符訪問對象的實例變量和C語言中使用點操作符訪問結(jié)構(gòu)體的成員意義是不一樣的墨微。訪問對象的實例變量的最正統(tǒng)的方法是通過 -> 操作符來訪問道媚。編譯器在碰到點操作符的時候并沒有直接訪問實例變量而是調(diào)用了訪問方法。
何時使用點操作符:
沒有參數(shù)的方法翘县,無論其是不是和屬性相關(guān)最域,都可以通過點操作符來調(diào)用。但原則上還是只對屬性聲明中定義的屬性應(yīng)用點操縱符锈麸。
使用點操作符會帶來調(diào)用方法的負(fù)擔(dān)镀脂,影響性能。
嚴(yán)格來說忘伞,使用依賴于實現(xiàn)的方式來訪問實例變量是不允許的薄翅,所以應(yīng)避免直接訪問實例變量沙兰。但屬性對應(yīng)的訪問方法則一定要直接訪問實例變量。
此外翘魄,在初始化方法中通過點操作符訪問屬性的時候要注意鼎天,因為初始化方法執(zhí)行的時候這個實例還沒完成初始化,屬性對應(yīng)的訪問方法有可能還沒生成暑竟。