1. 程式人生 > >retain、strong、weak、assign區別

retain、strong、weak、assign區別

在網上看到一個解釋weak和strong的例子,感覺挺形象的,如下:
一、weak和strong的區別
  (weak和strong)不同的是 當一個物件不再有strong型別的指標指向它的時候 它會被釋放  ,即使還有weak型指標指向它。
  一旦最後一個strong型指標離去 ,這個物件將被釋放,所有剩餘的weak型指標都將被清除。
  可能有個例子形容是妥當的。
  想象我們的物件是一條狗,狗想要跑掉(被釋放)。
  strong型指標就像是栓住的狗。只要你用牽繩掛住狗,狗就不會跑掉。如果有5個人牽著一條狗(5個strong型指標指向1個物件),除非5個牽繩都脫落 ,否著狗是不會跑掉的。
  weak型指標就像是一個小孩指著狗喊到:“看!一隻狗在那” 只要狗一直被栓著,小孩就能看到狗,(weak指標)會一直指向它。只要狗的牽繩脫落,狗就會跑掉,不管有多少小孩在看著它。
  只要最後一個strong型指標不再指向物件,那麼物件就會被釋放,同時所有的weak型指標都將會被清除。

二、weak和assign的區別
1、assign是指標賦值,不對引用計數操作,使用之後如果沒有置為nil,可能就會產生野指標;而weak一旦不進行使用後,永遠不會使用了,就不會產生野指標!

三、
alloc 物件分配後引用計數為1
retain 物件的引用計數+1
copy copy 一個物件變成新的物件(新記憶體地址) 引用計數為1 原來物件計數不變

release 物件引用計數-1 如果為0釋放記憶體
autorelease 物件引用計數-1 如果為0不馬上釋放,最近一個個pool時釋放


四、
1.假設你用malloc分配了一塊記憶體,並且把它的地址賦值給了指標a,後來你希望指標b也共享這塊記憶體,於是你又把a賦值給(assign)了b。此時a和b指向同一塊記憶體,請問當a不再需要這塊記憶體,能否直接釋放它?答案是否定的,因為a並不知道b是否還在使用這塊記憶體,如果a釋放了,那麼b在使用這塊記憶體的時候會引起程式crash掉。2.瞭解到1中assign的問題,那麼如何解決?最簡單的一個方法就是使用引用計數(referencecounting),還是上面的那個例子,我們給那塊記憶體設一個引用計數,當記憶體被分配並且賦值給a時,引用計數是1。當把a賦值給b時引用計數增加到2。這時如果a不再使用這塊記憶體,它只需要把引用計數減1,表明自己不再擁有這塊記憶體。b不再使用這塊記憶體時也把引用計數減1。當引用計數變為0的時候,代表該記憶體不再被任何指標所引用,系統可以把它直接釋放掉。3.上面兩點其實就是assign和retain的區別,assign就是直接賦值,從而可能引起1中的問題,當資料為int,float等原生型別時,可以使用assign。retain就如2中所述,使用了引用計數,retain引起引用計數加1,release引起引用計數減1,當引用計數為0時,dealloc函式被呼叫,記憶體被回收。4.copy是在你不希望a和b共享一塊記憶體時會使用到。a和b各自有自己的記憶體。 五、 1.assign:
 用於非指標變數。用於基礎資料型別 (例如NSInteger)和C資料型別(int, float, double, char)另外還有id反正記住:前面不需要加 “*” 的就用assign吧,weak 就是相當於assign2. retian :釋放舊的物件,將舊物件的值賦予輸入物件,再提高輸入物件的索引計數為1,用於指標變數。就是說你定義了一個變數,然後這個變數在程式的執行過程中會被更改,並且影響到其他方法。xcode4.3及以後版本上面開發,retian和strong都是一樣的,沒區別3. copy : 效果其實和retain沒什麼兩樣,唯一的區別就是copy只用於NSString而不能用於
NSMutableString,如果當一個類繼承NSObject,那麼這個類裡面的屬性需要使用copy。retain是指標拷貝,copy是內容拷貝。 六、

 strong 和weak

iOS 5 中對屬性的設定新增了strong 和weak關鍵字來修飾屬性(iOS 5之前不支援ARC)

strong 用來修飾強引用的屬性;

@property (strong) SomeClass * aObject; 對應原來的 @property (retain) SomeClass * aObject; 和 @property (copy)SomeClass * aObject; weak 用來修飾弱引用的屬性; @property (weak) SomeClass * aObject; 對應原來的 @property (assign) SomeClass * aObject;