@property 是 Obj-C 2.0 版中開始提供的一種功能,目的是要簡化一個實體變數設定的過程。如 setter 與 getter 小節所述,一個實體變數多半需要寫個數行的 setter 與 getter,但其使用的 Code 都是幾乎是固定模式的,於是所有東西都可以用一行 (XCode 4.3 之前為兩行) 指令來宣告。
@interface Car : NSObject
@property int speed;
@end
@implementation Car
@end
這段程式實際上的功能和下一段是相同的
@interface Car : NSObject{
int _speed;
@end
@implementation Car
-(int)speed{
return _speed;
}
-(void)setSpeed:(int)speed{
_speed=speed;
}
@end
請注意 @property int speed 時,實體變數名稱為 _speed 不是 speed。
很重要的一件事就是 setter 與 getter 如果是寫成這個模式,就可以使用【點運算子】來存取,不一定要用傳送訊息的方式來呼叫方法。點運算子的寫用如同存取 C 的結構,例如實體為 theCar,setter 就可以寫成 theCar.speed=100,就相當於 [theCar setSpeed:100] 。要使用 getter 印出 speed ,也可以直接用點運算子 NSLog(@"%i",theCar.speed) 就可以了,也就等於NSLoge(@"%i", [theCar speed])。
點運算子主要的目的是讓程式容易閱讀,也可以和 C 語言的結構體混用。
@property 可以有一些參數
- getter=getterName,setter=setterName
設置setter與getter的方法名,一般使用默認的名字即可。 - readwrite,readonly
預設為 readwrite , 但如你把它設為 readonly 將只生成getter方法,使用者將無法直接寫入值。 - assign,retain,copy
這組與記憶體管理有關,如果你是使用 ARC 記憶體管理,就不會用到這一組,而是用 strong,weak 這一組如果想深入了解,請Google Objective 的記憶體管理方面的資料(不用 ARC的)
assign : 調用setter方法時直接賦值,不進行任何retain操作。
retain : 調用setter方法時,先release舊值,然後對賦予的新值執行retain,相當於一次指針的拷貝。
copy : 調用 setter方法時,進行Copy操作,與retain處理流程一樣,先release舊值,再Copy出新的對象,retainCount為1。其實是建立一個新的對象。 - strong, weak
這組也是與記憶體管理有關,strong代表我 “擁有” 有這個變數,其他人不能動到它,但我們在寫 delegate 時,因為他是代理人,實際生成是另一個東西來建構,所以會用到 weak。 - atomic, nonatomic
原子/非原子性訪問,不加同步,多線程並發訪問會提高性能。 atomic是Objc使用的一種線程保護技術,基本上來講,是防止在寫未完成的時候被另外一個線程讀取,造成數據錯誤。而這種機制是耗費系統資源的,所以在iPhone這種小型設備上,如果沒有使用多線程間的通訊編程,那麼 nonatomic 是一個非常好的選擇。
其中後三項,初學者可能很難理解。如果一時無法理解也沒關係,如果沒有特別原因,可以先用【基本資料類型不設參數,類別資料類型設 (nonatomic, strong)】設就可以了,其他的等到學習 delegate,多線程,自訂 setter 等需要參數時,文件中有特別註明是,再來理解就可以了。
@property 參數使用範例如下:
@property (nonatomic, strong) NSString *carType;
使用 @property 之後還是可以寫 setter 與 getter 的,一定要用 變數名稱 做為 getter 名稱,而用 get變數名稱:變數名稱 做為 setter 名稱,不必宣告方法。例如:
@interface Car : NSObject
@property int speed;
@end
@implementation Car
-(void)setSpeed:(int)speed{
if(speed<0 ) speed=0;
if(speed>300) speed=300;
_speed=speed;
}
@end
就可以完成有限速 300 且不能為負數的 setter,其他的 getter / 宣告方法 / 就交給 @property 就好了。
註:
XCode 4.3 之前,每一個 @property 都要在 @implementation 加上 @synthesize 變數名稱 或 @synthesize 變數名稱 =_ 變數名稱 但 4.4 之後就自動化了,如果沒寫,就等於寫了 @synthesize 變數名稱 =_ 變數名稱,而 @synthesize 的設定,也可以改變變數的名稱,如 【@synthesize 變數名稱;】 時,變數名稱前面就不再有 underline, 有興趣的讀可以查一下 @synthesize 的功能。
留言列表