2014年10月9日 星期四

@property 介紹

@property是在Objective-C 2.0(2006年)新加入的功能,目的是要簡化一個實體變數(instance variable, 簡稱ivar)設定的過程。
在沒有@property功能之前,要自己宣告setter跟getter。

各種屬性介紹

讀寫相關:
  • readwrite(default)
  • readonly

記憶體管理相關:
  • Automatic Reference Counting(ARC):這部分對初學者來說比較難懂,簡單講,絕大部分時我們會用的是strong,weak是一些比較進階的功能才會用到,所以初學者每次在設定的時候用strong就可以了。如果想要知道背後詳細的原理及解釋可以看我另外寫的這篇Automatic Reference Counting(ARC)
    • strong:
    • weak:
  • Manual Reference Counting(MRC):這是上一代的記憶體管理方式,現在已經不用了,因為ARC遠遠比MRC好用太多了,只需要知道有這些屬性的存在就可以了,因為在網路上還是很容易找到比較舊的文章是用MRC。
    • assign(default) : 直接指派,不進行 retain
    • retain : 先 release 再 retain 新值
    • copy : 先 release 再 copy 新值

多執行緒相關:對初學者來說,這部分比較難懂,我後面打的解釋是結果論,如果想要知道兩個屬性背後實際上是怎麼回事可以看這篇atomic vs. nonatomic
  • nonatomic : 沒有要用多執行序就選這個,但不知道為什麼Apple並沒有把這個屬性設為預設,所以幾乎是每次都要加上這個屬性。
  • atomic(default) : 如果要使用多執行序就選這個。

setter/getter相關(accessors):
  • setter = setterName:重新命名setter名稱
  • getter = getterName:重新命名getter名稱,最常改的方式是在原本的名稱加「is」ex:@property (nonatomic, getter = isChosen) BOOL chosen;

@synthesize

@property DECLARES the accessors for your property, @synthesize will IMPLEMENT them.
原本是在@interface的程式
-(int) price;
-(void) setPrice: (int) p;
可以只要寫
@property int price;

在@implementation的程式從
-(int) price
{
  return price;
}

-(void) setPrice: (int) p
{
  price = p;
}
變成只要寫
@synthesize price;
Xcode 4.3 之前,每一個 @property 都要在 @implementation 加上 @synthesize 變數名稱 或 @synthesize 變數名稱 =_ 變數名稱 但 4.4 之後就自動化了,如果沒寫,就等於寫了 @synthesize 變數名稱 =_ 變數名稱,而 @synthesize 的設定,也可以改變變數的名稱,如 【@synthesize 變數名稱;】 時,變數名稱前面就不再有 underline, 有興趣的讀可以查一下 @synthesize 的功能。

2012年Objective-C加入了不少新功能,@synthesize變成預設值,現在有沒有寫@synthesize的差別只在於你取用變數的方式:
有寫@synthesize
price
沒有寫@synthesize
self.price

自訂setter/getter

但如果你要自訂自己的setter/getter的話,你就要自己寫setter/getter 函數,系統會以你自己寫的函數為主。
例如我們自訂setter:
-(void)setPrice:(int)p
{
  price = p * 2;
}
這樣的話當我們在給price值的時候,就會自動變成兩倍,也就是當我們打的程式碼是:
price = 3;
price的值實際上是6而不是3,因為3傳入時還會被乘以二。


Attribute 屬性

在2006年發佈了Objective-C 2.0後,Objective-C也可以使用「.」來存取物件的屬性
原本要設值是這樣
[b setPrice:300];
就可以寫成
b.price = 300;

不過在高見龍的部落格裡有提到點語法的一個小細節,有可能造成無窮回圈:
-(void) setPrice: (int) p
{
  self.price = p;
}
如果在自訂的setter裡使用了點語法,那就會不斷的呼叫自己(setter函數),變成無窮迴圈。


    整理來源:
    http://stackoverflow.com/questions/9162926/ios-property-declaration-clarification
    http://pydoing.blogspot.tw/2012/08/objc-property-and-synthesize.html
    http://shenfive.pixnet.net/blog/post/48054812-@property-
    http://blog.eddie.com.tw/2010/12/08/property-and-synthesize/