ios記憶體管理:ios 不同mac os,ios沒有記憶體回收機制(mac os有),主要原因是行動裝置資源有限?還是他的專屬架構cocoa不支援?或兩者,哈哈哈,列出來了,請意會。所以在ios編程中記憶體管理很重要--引用計數器(rc),如果不注意,就可能出現記憶體流失leak 或者 bad access(訪問一個已銷毀的對象地址)錯誤
- 記憶體管理的基本原則:您只能登出(release)或釋放(autorelease)您擁有的對象,‘擁有’的意思是您擁有一個對象的所有權,按照cocoa的命名規則,一般您使用名字以alloc,copy*,new*(xxx*表示包含xxx)的方法建立一個對象a時,您擁有a的所有權。抑或使用retain獲得一個對象的所有權。
- 使用release和autorelease釋放一個對象的所有權,release的意思是立即釋放,對象引用計數器 -=1(注意使用對象xxxcount查看對象引用計數可能造成誤解。按照xxx說法,當對象的引用計數==0時,調用對象 delloc,然後銷毀對象,但當你調用對象的xxxcount查看對象的引用數時往往大於你的預期值0,這個不必擔心,因為你不清楚這個架構的類之間的關係,你也不需要瞭解。你只需要做的是保證您的代碼裡,get(得到所有權)
-->release/autorelease所有權。在ios中你只不過是一個過客,不是主人,訂房要退房(不夠準確?確實,訂房沒有所有權啊)....,或者換一種說法有借有還。
- 上面第二點只說release,在這說一下autorelease,auto...(表示autorelease,下面一樣)的意思是‘將會發送release訊息釋放’,其實是把對象放進對應的自動釋放池裡(就近原則?),至於到底什麼時候釋放呢?這個與autoreleasepool(自動釋放池)有關,當release/drain 池之前,會發送一條release訊息給池裡每一個對象。而自動釋放池有他的範圍。好,下面說一下,autorelease用得最多的地方...
-(void) creatObject{ NSString *s = [[NSString alloc] init]//建立字串對象s return [s autorelease] //要養成好習慣,今天的事今天作 //返回方法裡您建立的對象(請意會--)時,返回前,把它放進自動釋放池}
- autoreleasepool(自動釋放池),cocoa應用程式總期望有一個可用的自動釋放池,如果自動釋放池不可用或不存在,那麼自動釋放對象則無法釋放,導致記憶體流失(leak)。
- 自動釋放池可以嵌套,嵌套是什嗎?看代碼:
-(void)run{ NSAutoReleasePool *pool= [[NSAutoReleasePool alloc] init] //虛擬碼,意會 ... //some code here NSAutoReleasePool *innerPool= [[NSAutoReleasePool alloc] init] //嵌套自動釋放池 ... //some code here [innerPool release] [pool release]}
其實,在cocoa應用程式啟動並執行堆棧中,但您建立了一個自動釋放池,它會被添加到棧頂(隨著方法),所以,為了防止記憶體流失,棧底應該也要有一個自動釋放池。君不見,ios main方法中,不也是有個...。自動釋放池的範圍是
init -》release(在相同的上下環境,可以簡陋地認為在同一方法),內嵌套自動釋放池,通常用在建立大量臨時對象。
-(void)run{ for (int i= 0,i <99999,i++){ NSAutoReleasePool *innerpool= [[NSAutoReleasePool alloc] init] NSString *s = [[NSString alloc] init] ... //some code here [s autorelease] [innerpool release]}}
- 線程與池,每個線程都有他們自己的線程棧,所以意會第四點紅體字
- 異常與池,解析看第四點紅體字
- 在‘雞生蛋,蛋生雞’的問題上,只需確認雞能生蛋就行了
- (未完待續)