Objective-C @property

Objective-C @property
===

我相信對於ios開發者來講,Objective-C的@property都是不太陌生的一個概念。不過最近我參加了一次面試,在問到相關問題的時候仍是感受如鯁在喉,可見一個簡單的概念想要清晰的去解釋仍是須要深入的理解。故而寫這篇博客來鞏固一下對於OC的@property的理解。

---
##@property是什麼
@property是編譯器的指令

什麼是編譯器的指令,編譯器指令就是用來告訴編譯器要作什麼

@property 告訴編譯器聲明屬性的訪問器(getter/setter)方法

和@property配對使用的還有@synthesize指令

@synthesize指令:告訴編譯器,生成或合成屬性的訪問器(getter/setter)方法

舉例,本來咱們須要寫以下代碼
```
@interface PropertyTest : NSObject    
{        
    NSString *name;    
}    
- (NSString *)name;    
- (void)setName:(NSString *)newName;    
@end
```
使用@property和指令後
```
@interface PropertyTest : NSObject    
{
    NSString *name;
}    
@property (nonatomic, strong) name; 
@end
```
看上去不錯,簡潔漂亮。

若是屬性不少,@property能省下的代碼量將會至關可觀。

##@property的attribute
細心點的就會發現,每一個@property括號後面都跟了一個括號,括號裏面是什麼東西呢?括號裏面呢是@property的attribute,能夠理解爲@property的設置。

括號裏面設置(attribute)不一樣,property所生成的setter方法也就不一樣。

有哪些設置呢?我簡單列舉一下:

   * 
atomic(默認):atomic意爲操做是原子的,意味着只有一個線程訪問實例變量。
   * 
nonatomic: nonatomic跟atomic恰好相反。表示非原子的,能夠被多個線程訪問。
   * 
readwrite(默認):readwrite是默認的,表示同時擁有setter和getter。
   * 
readonly: readonly 表示只有getter沒有setter。
   * 
retain:釋放舊值,retain新值
   * 
assign(默認):用於值類型,如int、float、double和NSInteger,CGFloat等表示單純的複製。還包括不存在全部權關係的對象,好比常見的delegate。
   * 
strong:是在ARC伴隨IOS引入的時候引入的關鍵字是retain的一個可選的替代。表示實例變量對傳入的參數要有全部權關係即強引用。strong跟retain的意思相同併產生相同的代碼,可是語意上更好更能體現對象的關係。
   * 
weak: weak跟assign的效果類似,不一樣的是weak在對象被回收以後自動設置爲nil。並且weak智能用在iOS 5或之後的版本,對於以前的版本,使用unsafe_unretained。
   * 
copy:copy是爲是實例變量保留一個本身的副本。

atomic/nonatomic readwrite/readonly的功能都相對來講好理解

剩下的attribute跟內存管理有點關係,下面咱們講點內存管理和@property的關係


---
##property和內存管理
內存管理聽上去很高大上有木有,內存管理博大精深,不過內存管理是一個籠統的概念,並非一個很專業的技術概念。在Objective-C裏咱們主要經過引用計數來達到內存管理的目的。

好吧,又來了一個概念叫引用計數。跟標題不符合啊!標題黨啊!不要急,不要急,其實引用計數和內存管理是密不可分的。舉一個二一點的例子。內存管理就是吃飽飯,那怎麼樣能吃飽飯呢?你吃米飯能吃飽,你吃麪條也能吃飽。在OC裏內存管理就是經過引用計數來完成,而在java裏內存管理就是經過垃圾回收機制來完成。 因此接下來咱們來說講引用計數。 

>引用計數 
>
>這是一種古老但有效的內存管理方式。每一個對象(特指:類的實例)內部都有一個retainCount的引用計數,對象剛被建立時,retainCount爲1,能夠手動調用retain方法使retainCount+1,一樣也能夠手動調用release方法使retainCount-1,調用release方法時,若是retainCount值減到0,系統將自動調用對象的dealloc方法(相似於c#中的dispose方法),開發人員能夠在dealloc中釋放或清理資源。


上面一段話呢是從參考資料裏複製出來的,簡單的來講呢,當你建立一個對象的時候,對象裏面就有了一個計數retainCount,初始值爲1。當你對對象作一些操做的時候能夠對這個retainCount的值作一些改變。那哪些操做能夠更改這個計數呢? 簡單列舉一下:

   * 
retain 計數加1。
   * 
release計數減1
   * 
autorelease 計數減1,可是不是當即執行,而是以推遲的方式。

經過這些操做呢,咱們對retainCount計數作出了修改,若是計數變爲0的時候就會自動調用dealloc方法來釋放對象和內存。

屁話講了一堆,那property和內存管理有毛關係,或者說property和引用計數有毛關係。 好吧,開始進入正題了.

還記得上一節說的那個property的設置(attribute)嗎 

某些attribute會生成不一樣的set方法。那些不一樣的set方法裏就有跟內存管理相關的內容。 讓咱們來看看哪些設置是根內存管理有關係的,讓我來一一列舉出來。

**設置了assgin以後的setter方法**
```
- (void)setName:(NSString *)newName 
{ 
    name = newName;
}
```
**設置了retain以後的setter方法** 
```
- (void)setName:(NSString *)newName 
{ 
    if (newName != name) { 
        [name release]; // release舊值 
        name = [newName retain] //retain新值 
    } 
}
```
**設置了copy以後的setter方法**
```
- (void)setName:(NSString *)newName 
{ 
    if (newName != name) { 
        [name release]; // release舊值 
        name = [newName copy] //copy新值 
    } 
}
```

跟內存相關的呢主要是這三個attribute

還有兩個attribute也要說起一下,就是 weak 和 strong

retain 和 strong 功能基本一致

weak能在對象自動銷燬的時候自動賦值nil,主要用於解決循環應用的問題

property若是擁有以上設置,成員變量的get方法裏就會有相應的retain和release操做。這就是爲何說property跟內存管理有關係了。

##PS
以上就是我對@property的簡單理解,隨着IOS開發的經驗增長,對OC有更深刻的理解後,我會繼續補充。文章中可能有稍許紕漏,若是有疑問,煩請提出來一塊兒討論!


**參考資料**:

http://www.cnblogs.com/andyque/archive/2011/08/03/2125728.html
http://www.cnblogs.com/yjmyzz/archive/2011/02/23/1958961.html

相關文章
相關標籤/搜索