2013年6月21日 星期五

iOS_ARC_note

基本功實在不太好,每次在寫code的時候都忽略記憶體的重要,筆記一下順便熟悉記憶體該注意的事項
找到了一個不錯的網站
以下是從該網站的重點整理:
1. ARC(Automatic Reference Counting)為WWDC2011年與iOS5所提出的:
   |- 像往常一樣寫code,不過不用再像MRC一樣寫retain, release, autorelease
   |- ARC得好處在開啓時,編譯器會自動在程式碼適合的地方插入retain, release, autorelease
2. MRC的一些基本觀念:
   |- 如果需要持有一個對象,那麼對其發送retain 如果之後不再使用該對象,那麼需要對其發送release(或者autorealse) 
   |- 每一次對retain,alloc或者new的調用,需要對應一次release或autorealse調用 
   |- 開發者雖然知道上述的概念,不過難免會犯錯
3. ARC機制:
   |- 使用MRC時需要自己用retain來保持一個對象,在ARC中不用在retain,只需要用一個pointer指向該對象即可
   |- 在ARC時,只要pointer沒有被設成nil,對象就會一直保持
   |- 當pointer被賦予新的值時,該對象會被release一次
4. 該網站舉的例子1:
NSString *firstName = self.textField.text;
   |- fileName指到NSString對象,此時該對象(textField.text)會被hold住
   |- 這時fileName持有惹@"oneV"


   |- 一個對象可以不只有一個持有者,在例子中有兩個持有者a. fileName b. textField.text
   |- 按照MRC的概念,現在有兩個持有者,所以retainCount = 2


   |- 如果這時在textField內輸入其他字ex:@"onevcat"
   |- 原來的對象(@"oneV")仍然存在,因為還有一個pointer仍持有它


   
   |- 如果這時連fileName都被設定成新的值時,或是超出作用範圍空間(local variable)
   |- 此時不再有pointer持有@"oneV",在ARC的情況下就會把@"oneV"給自動release


   |- 在上述的例子中,fileName和textField.text pointer所使用的關鍵字是strong,意味者
      |- 該pointer所指到的對象就不會被銷毀
   |- ARC的基本規則->只要被strong所指到,那麼它將不會被銷毀,如果沒有被任何的strong pointer所指到就會被銷毀
   |- strong和MRC中retain的property比較像
5. 該網站的例子2:
__weak NSString *weakName = self.textField.text;

   |- 有strong,肯定有weak
   |- weak類型的pointer也可以指向對象,但不會持有該對象
   |- 下圖declare一個weak的pointer-> weakName,他不持有@"onevcat"


   |- 如果self.textField.text的內容發生改變的時候,只要某個對象被strong pointer指到就不會被銷毀
   |- 如果沒有被任何的strong給指到,那麼該對象就會被銷毀
   |- 此時@"onevcat"沒有被任何strong pointer所指到,@"onevcat"被銷毀
   |- 在ARC的作用下,指向該對象的weak pointer會被設為nil
   


   |- 在大部分的情況下weak pointer並不會很常用
   |- 比較常見的用法是在兩個對象之間存在包含關係時:
      |- 對象一有一個strong pointer指向對象二
      |- 對象二有一個weak pointer指向對象一 -> 該方式可以避免循環持有
      |- 常見的例子 -> delegate的設計模式
      |- viewController有一個strong pointer指向負責管理的UITableView
      |- 而UITableView的datasource, delegate都是指向viewController的weak pointer
      |- weak和MRC的assign比較相似,但weak pointer更聰明一些(會指向nil)
      |- 

6. 一些小注意:
__weak NSString *str = [[ NSString alloc ] initWithFormat: … ]; 
NSLog ( @"%@" , str ); //輸出是"(null)" 
上面程式碼說明str為weak,並不會持有alloc出來的對象,所以alloc出來之後馬上被銷毀
@property ( nonatomic , strong ) NSString *firstName; 
@property ( nonatomic , weak ) id delegate; 
上面再說明在ARC中只要把在MRC中所使用的retain, assign換成strong, weak即可
註:delegate使用weak比較好
id obj = [ array objectAtIndex: 0 ];   
[ array removeObjectAtIndex: 0 ];   
NSLog ( @"%@" , obj ); 
上面程式碼如果是在MRC的時候,因為array中index 0的物件被銷毀,所以array也就跟著被釋放掉,所以obj指向delloced的對象,所以在MRC的時候NSLog會出現EXC_BAD_ACCESS,城市就會當掉,但是在ARC中因為有strong的obj所指向該對象,即使array將obj給移除,他仍然被指針所持有
ARC是在比較high level的object的framework中使用,ex:UIKit,如果遇到比較底層的framework時(ex: Core Foundation)仍然需要面對MRC中的概念(retain, release)

沒有留言:

張貼留言