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