日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(转)Objective-C Autorelease Pools(自动释放池)详解

發布時間:2024/4/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (转)Objective-C Autorelease Pools(自动释放池)详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本篇將給您介紹”Autorelease Pools”(自動釋放池)在應用中的使用技巧。

1,Autorelease Pools概要

一個”Autorelease Pool”實例中“包含”其它各種調用了”autorelease”方法的對象。當它釋放時,其中所有被管理對象都會收到”relrease”的消信。注意,同一個對象可以被多次調用”autorelease”方法,并可以放到同一個”Autorelease Pool”中。引入這個自動釋放池機制,對象的”autorelease”方法代替”relrease”方法可以延長它的生命周期,直接到當前”Autorelrease Pool”釋放。如果想讓此對象的生命周期超過”Autorelease Pool”,還可以再次”retain”,呵呵,有意思吧?且讓我慢慢道來。

Cocoa總是認為當前至少有一個”Autorelease Pool”對象是可用的。若此對象并不存在,你調用的”autorelease”的所有對象都不會被自動釋放掉,可想而知,造成內存泄露。Cocoa把這個錯誤信息寫入日志??僅僅是為了以后分析。

你可以用”alloc”與”init”方法創建一個”NSAutoreleasePool”對象,并且可以調用”release”或”drain”(”release”與”drain”的區別是”drain”在有GC的環境中會引起GC回收操作,”release”反之。但在非GC環境中,兩者相同。官方的說法是為了程序的兼容性,應該考慮用”drain”代替”release”,)方法來回收它(調用它的”autorelease”或”retain”方法會引起異常)。在一個完整的上下文最后”Autorelease Pool”對象應該被”release”掉(在方法內或一段循環體內創建的”Autorelease Pool”對象)。

“Autorelease Pools”的所有實例在棧中管理(我們暫時叫他“自動釋放池棧”),并且它們是可以被嵌套的(父生子,子生孫。。。子子孫孫 ^_^)。例如,當我們創建一個”Autorelease Pool”對象后,它就被自動放到“自動釋放池棧”的棧頂。當本池對象回收時,它就隨之從這個棧中POP掉。那么也就是說,當任何一個對象調用”autorelease”方法后,它會被放入當前線程中當前棧頂的自動釋放池中。

接下來我們聊聊”Autorelease Pools”的嵌套問題。在你的應用中,你可以任意多的創建”Autorelease Pool”對象,而這些對象被當前線程的“自動釋放池棧”所管理。那么除了一個接一個的順序創建并銷毀它的情況外,還有一種使用方式,就是嵌套式的創建與使用。例如:在你的主函數創建了一個”autorelease pool”,然后又調用了創建了”autorelease pool”實例的其它方法;或是在外循環中創建了”Autorelease Pool”的實例,而內循環中也做了相同的事情。有意思吧,呵呵,嵌套的機制使父Pool實例釋放后,它的所有子Pool也將釋放。但這里還存在一些副作用,后續文章會詳細討論。

“Application kit”在一個事件循環里會自動創建一個”autorelease pool”。像鼠標鍵的按下與釋放,所以你編寫的代碼通常不需要考慮太多這方面的事情。當然,有以下三種情況你會創建與銷毀自己的Pool實例:

?? 1,應用不是基于”Application Kit”,像”Command-line tool”,因為它并沒有內置的”autorelease pools”的支持。
?? 2,創建線程,你必需在線程開始時創建一個”Autorelease Pool”實例。反之,會造成內存池露(會在以后的文章詳細說明線程與池的技巧)。
?? 3,一個循環內創建了太多的臨時對象,你應該為他們創建一個”Autorelease Pool”對象,并在下次循還前銷毀它們。

2,自動釋放池中的”Non-AppKit”應用

在”Non-AppKit”應用中使用自動釋放池的機制其實是相當簡單的事情。你僅僅需要在main()起始處創建”Autorelease Pool”對象,并在結尾處釋放掉它。就像在Xcode的Foundation Tool的創建模版里寫的一樣。這個確保你在應用生命周期內至少有一個”Autorelease Pool”是可用的。但是,這也使所有在此期間的所有”autorelease”的對象都必需在應用結束后才被釋放。這也許會引起在應用的使用中不斷的增長,所以,你仍然考慮在不同的作用域創建新的”Autorelease Pool”。

大多應用中都存在各種級別的循環機制。在這些應用中,你可以在每個循環內的開頭創建一個”Autorelease Pool”對象,并在結尾處釋放掉它。

例如:


void main()
{
??? NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

??? NSArray *args = [[NSProcessInfo processInfo] arguments];
??? unsigned count, limit = [args count];

??? for (count = 0; count < limit; count++)
??? {
??????? NSAutoreleasePool *loopPool = [[NSAutoreleasePool alloc] init];
??????? NSString *fileContents;
??????? NSString *fileName;

??????? fileName = [args objectAtIndex:count];
??????? fileContents = [[[NSString alloc] initWithContentsOfFile:fileName] autorelease];
??????? // this is equivalent to using stringWithContentsOfFile:

??????? /* Process the file, creating and autoreleasing more objects. */

??????? [loopPool release];
??? }

??? /* Do whatever cleanup is needed. */
??? [pool drain];

??? exit (EXIT_SUCCESS);
}

在命令行中處理所有以參數傳來的文件。一次循環處理一個文件。在循環的開頭創建一個”NSAutoreleasePool”對象,并在循環結束時釋放掉。因此,任何在其中創建并調用“autorelease”的對象都將添加到這個Pool實例中,當本池被釋放后,這些對象也將被回收。注意,任何在作用域內創建的”autoreleased”對象(像”fileName”),雖然并沒有顯示的調用”autorelease”方法,但都將被當前池所管理并釋放。

先到這里,休息,休息一下??

本文翻譯自:
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-SW2

轉載于:https://www.cnblogs.com/greywolf/archive/2012/11/22/2782440.html

總結

以上是生活随笔為你收集整理的(转)Objective-C Autorelease Pools(自动释放池)详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。