【iOS面試系列-1】iOS中@property 後assign,copy,retain,weak,strong的意義與區別(必考-必須詳細掌握),ios@property
來源:網路
assign: 普通(簡單)賦值,一般常用於基礎資料型別 (Elementary Data Type),常見委託設計模式,一次來防止循環參考。不更改索引計數(Reference Counting)。 對基礎資料類型 (NSInteger,CGFloat)和C資料類型(int, float, double, char, 等等)
retain:保留計數,獲得到了對象的所有權,引用計數在原有基礎上+1.釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1 。我們給那塊記憶體設一個引用計數,當記憶體被分配並且賦值給a時,引用計數是1。當把a賦值給b時引用計數增加到 2。這時如果a不再使用這塊記憶體,它只需要把引用計數減1,表明自己不再擁有這塊記憶體。b不再使用這塊記憶體時也把引用計數減1。當引用計數變為0的時候,代表該記憶體不再被任何指標所引用,系統可以把它直接釋放掉。retain之後count加一。alloc之後count就是1,release就會調用dealloc銷毀這個對象。如果 retain,需要release兩次。通常在method中把參數賦給成員變數時需要retain。NSArray對象會retain(retain值加一)任何數組中的對象。當NSArray被卸載(dealloc)的時候,所有數組中的對象會 被 執行一次釋放(retain值減一)。不僅僅是NSArray,任何收集類(Collection Classes)都執行類似操作。例如 NSDictionary,甚至UINavigationController。
copy: 建立一個索引計數為1的對象,然後釋放舊對象 。用來複製對象,一般字串用copy,Foundation中不可變對象使用copy效果相當於retain,只是引用計數+1.
autorelease 原理:
autorelease和範圍沒有任何關係!
a.先建立一個autorelease pool
b.對象從這個autorelease pool裡面產生。
c.對象產生 之後調用autorelease函數,這個函數的作用僅僅是在autorelease pool中做個標記,讓pool記得將來release一下這個對象。
d.程式結束時,pool本身也需要rerlease, 此時pool會把每一個標記為autorelease的對象release一次。如果某個對象此時retain count大於1,這個對象還是沒有被銷毀。
記住一點:如果這個對象是你alloc或者new出來的,你就需要調用release。如果使用autorelease,那麼僅在發生過retain的時候release一次(讓retain count始終為1)。
在ARC中,
strong(強引用)告訴編譯器自動幫我們插入retain,
weak(弱引用)是普通賦值相當於手動管理記憶體的assign。
-------------------------------------------------------------------------------------------------------------------------------------
區別
assign和retain的區別,assign就是直接賦值,從而可能引起1中的問題,當資料為int, float等原生類型時,可以使用assign。retain就如2中所述,使用了引用計數,retain引起引用計數加1, release引起引用計數減1,當引用計數為0時,dealloc函數被調用,記憶體被回收。
copy和retain
copy是建立一個新對象,copy是在你不希望a和b共用一塊記憶體時會使用到。a和b各自有自己的記憶體,retain是建立一個指標,引用對象計數加1。Copy屬性工作表示兩個對象內容相同,新的對象retain count為1 ,與舊有對象的引用計數無關,舊有對象沒有變化。copy減少對象對內容相關的依賴。retain屬性工作表示兩個對象地址相同(建立一個指標,指標拷貝),內容當然相同,這個對象的retain值+1也就是說,retain 是指標拷貝,copy 是內容拷貝。這裡指的是NSString,NSNumber等等一類的對象。
weak 和strong的區別:
(weak和strong)不同的是 當一個對象不再有strong類型的指標指向它的時候 它會被釋放 ,即使還有weak型指標指向它。
一旦最後一個strong型指標離去 ,這個對象將被釋放,所有剩餘的weak型指標都將被清除。
retain和strong的區別:在處理用strong聲明的Block屬性引發的問題時偶然發現的。在諸多教程中都會講到:聲明屬性時用strong或者retain效果是一樣的(貌似更多開發人員更傾向於用strong)。不過在聲明Block時,使用strong和retain會有截然不同的效果。strong會等於copy,而retain竟然等於assign!當然定義Block還是應該用copy(還有其他需要注意的地方,可以參考這篇文章:iOS: ARC和非ARC下使用Block屬性的問題),因為非ARC下不copy的Block會在棧中,ARC中的Block都會在堆上的。(http://blog.csdn.net/lvxiangan/article/details/50729888 不知道真的假的)
assign和weak的區別:weak比assign多了一個功能,當對象消失後自動把指標變成nil。assign是指標賦值,不對引用計數操作,使用之後如果沒有置為nil,可能就會產生野指標。當你的指標類型成員變數不需要進行強引用的時候,使用assign和weak都可以,比如一些delegate,否則使用strong
而基礎類型只能使用assign,assigin 可以用非 OC 對象,而 weak 必須用於 OC 對象
block和weak區別
__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基礎資料型別 (Elementary Data Type)。
__weak只能在ARC模式下使用,也只能修飾對象(NSString),不能修飾基礎資料型別 (Elementary Data Type)(int)。
block對象可以在block中被重新賦值,weak不可以。
atomic是Objc使用的一種線程保護技術,基本上來講,是防止在寫未完成的時候被另外一個線程讀取,造成資料錯誤。而這種機制是耗費系統資源的,所以在iPhone這種小型裝置上,如果沒有使用多線程間的通訊編程,那麼nonatomic是一個非常好的選擇。
【理解:http://www.cnblogs.com/langtianya/p/3691035.html】