@property 是 Obj-C 2.0 版中開始提供的一種功能,目的是要簡化一個實體變數設定的過程。如 setter 與 getter 小節所述,一個實體變數多半需要寫個數行的 setter 與 getter,但其使用的 Code 都是幾乎是固定模式的,於是所有東西都可以用一行 (XCode 4.3 之前為兩行) 指令來宣告。


使用 @property 宣告實體變數的語法是在類別的 @interface 區段,寫下

@property (參數1, 參數2....)  資料類別 變數名稱

其中參數可以略去不寫

如:

@interface Car : NSObject  
@property int speed;
@end

 

@implementation Car
@end

 
 

這段程式實際上的功能和下一段是相同的


@interface Car : NSObject{
    @private
    int  _speed;
}
-(int)speed;
-(void)setSpeed:(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 可以有一些參數

  1. getter=getterName,setter=setterName
    設置setter與getter的方法名,一般使用默認的名字即可。

  2. readwrite,readonly 
    預設為 readwrite , 但如你把它設為 readonly 將只生成getter方法,使用者將無法直接寫入值。

  3. assign,retain,copy 
    這組與記憶體管理有關,如果你是使用 ARC 記憶體管理,就不會用到這一組,而是用 strong,weak 這一組如果想深入了解,請Google Objective 的記憶體管理方面的資料(不用 ARC的)
    assign : 調用setter方法時直接賦值,不進行任何retain操作。
    retain : 調用setter方法時,先release舊值,然後對賦予的新值執行retain,相當於一次指針的拷貝。
    copy : 調用 setter方法時,進行Copy操作,與retain處理流程一樣,先release舊值,再Copy出新的對象,retainCount為1。其實是建立一個新的對象。

  4. strong, weak
    這組也是與記憶體管理有關,strong代表我 “擁有” 有這個變數,其他人不能動到它,但我們在寫  delegate 時,因為他是代理人,實際生成是另一個東西來建構,所以會用到 weak。

  5. 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 的功能。
  

arrow
arrow

    shenfive 發表在 痞客邦 留言(3) 人氣()