Object-c 2.0引入了屬性的概念,使得我們可以通過點方法來訪問對象的成員變量。假設有一個類爲A, 該類有一個成員對象爲mTest,mTest是一個類型爲B的對象,現在已經有了一個A類的實例對象爲a,爲了能夠用a.mTest 這樣的方式,我們需要做到以下兩點:
一、在頭文件中用以下方式將mTest聲明爲屬性
聲明屬性的語法:@property 類型 名字
比如我們可以這樣寫:@property(readwrite,nonatomic, retain) B *mTest;
這樣的聲明,最容易讓人迷惑的是類型部分,其實屬性主要分爲三類:
1. 讀寫屬性(readwrite/ readonly)
默認爲readwrite,表示該屬性既可以讀取,也可以給該屬性變量賦值;readonly則表示只能讀取該屬性變量。
2. 原子屬性 (atomicity/nonatomic)
原子屬性中,atomic是默認值,表示屬性是原子的,支持多線程併發訪問(在setter實現中加入了同步鎖),後者是非原子的,適合在非多線程環境中提升效率,沒有加入同步鎖。
3. Setter屬性 (assign/retain/copy)
如果屬性是對象類型,你需要使用retain,assign,copy參數,表示setter方法內部實現的時候,持有對象的方式。其中retain就是增加引用計數,強引用類型。assign就是變量的直接賦值,弱引用類型,也是默認值。copy就是把setter的參數複製一遍,再賦給成員變量。 如果你不給出持有對象的方式,編譯器就會給出警告。
屬性的setter類型與內存管理密切相關,要相當謹慎使用,很多內存錯誤以及程序的莫名其妙崩潰都是由於對屬性的不正確使用造成的。
二、在.m 文件中用以下方式合成對應的屬性讀取和設置函數
@synthesize mTest;
.m文件中有了上面這樣一行,編譯器就會自動合成getter函數,如果屬性是可賦值的(即屬性類型爲readwrite),還會合成setter函數。編譯器合成的getter函數名與屬性名相同,合成的setter函數名則形如setMTest(即將屬性的首字母大寫)。
實際上,我們也可以不用編譯器來幫我們合成方法,自己來實現屬性的存取方法。爲了這樣做,我們需要將@synthesize mTest; 這句去掉,同時在.m文件中實現以下兩個函數:
- - (B *) mTest
- {
- // .......
- }
- - void setMTest:(B*) b
- {
- // .............
- }
自己去實現存取方法是違背了屬性的初衷的,一般不採用,給大家講這個只是爲了說明問題,僅此而已。