基本功實在不太好,每次在寫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)
沒有留言:
張貼留言