iOS 學習@autoreleasepool{}
" ojc-c 是通過一種"referring counting"(引用計數)的方式來管理內存的, 對象在開始分配內存(alloc)的時候引用計數為一,以后每當碰到有alloc,new,[mutable]copy,retain的時候引用計數都會加一, 每當碰到release和autorelease的時候引用計數就會減一,如果此對象的計數變為了0, 就會被系統銷毀. "網摘
自從ARC以后 我們不需要手動釋放內存 但是有時候 我們仍然需要手動釋放,以便更加精準的管理內存問題.
這里 就用到@autoreleasepool{} //自動釋放內存池 “釋放池”
(1)@autoreleasepool{} 按棧的順序釋放內存 銷毀對象, 可以嵌套使用
(2)@autoreleasepool{} 相當于 做 autorelease / release 操作,如果把已經autorelease / release 的對象做 釋放池操作 就會報野指針錯誤. (ARC 好像這個問題就很少有了吧…)
舉例子
(1)循環創建臨時變量 或者說 短時間內創建大量變量 應該考慮使用 @autoreleasepool{}
這個例子 真是不勝枚舉啊
- (void)viewDidLoad { [super viewDidLoad]; [self test2]; } - (void)test2 { CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); for (int i = 0; i < 10000000; ++i) { @autoreleasepool { MethodDetailMusic *music = [[MethodDetailMusic alloc]init]; music.title = @"haha"; // NSLog(@"%@", music.title); } } NSLog(@"end - %f", CFAbsoluteTimeGetCurrent() - start); }
(1)是否有 @autoreleasepool {} 拿 Leak工具 跑了一次 看對比截圖


看前面幾個驚險的MB 就看出差別了吧
(2)@autoreleasepool {} 放在循環體外 和循環體內還是有很大差別的
//10000
2016-08-18 11:44:44.558 LearningTheroyDemo[40012:6355283] end - 0.002388
2016-08-18 11:45:49.970 LearningTheroyDemo[40032:6356878] end - 0.002540
//10000000(從這可以看出枚舉量越大 效率差別越明顯)
2016-08-18 11:47:30.521 LearningTheroyDemo[40071:6359862] end - 2.655450
2016-08-18 11:48:14.521 LearningTheroyDemo[40080:6361041] end - 2.932974
(2) 自己創建的線程 "detach thread", 有相對來說 很多需要釋放的對象,應該使用@autoreleasepool{} 否則內存會升高,但是 如果這個非關聯線程 "detach thread"沒有使用到cocoa的相關調用 就不必創建 autorelease pool.
第二段,大概是說如果創建POSIX 線程 做二級線程 這個就不能使用 cocoa ,不能使用 @autoreleasepool{}, 除非 cocoa
在多線程里面,并且是一級線程里面的對象.所以 在二級POSIX線程里面要使用cocoa必須有這個所謂的一級線程,并且要立即銷毀.所以 你要使用 cococa 要確保是在多線程里面 如何判斷 bla bla.
我覺得 我翻譯的還行 沒出什么原則的bug 網上好多帖子 說的 不是不對 就是不準 , 根本沒說明白 detach thread 里面 到底 能不能用 @autoreleasepool{} ? 簡單的來說 如果 創建了 很多需要釋放的對象 就可以用啊 ,因為 我們常用的多線程(NSOperation NSthread GCD ) 是滿足需求沒有例外的 ,就是 官方文檔提到的這個 "POSIX thread" ( 是調用pthread_create來創建的線程 C語言底層部分的知識了此處不再擴展,需要深究時候及時學習)不能使用@autoreleasepool{},但是也給了一個 處理方案...
If you are making Cocoa calls outside of the Application Kit’s main thread—for example if you create a Foundation-only application or if you detach a thread—you need to create your own autorelease pool.
If your application or thread is long-lived and potentially generates a lot of autoreleased objects, you should periodically drain and create autorelease pools (like the Application Kit does on the main thread); otherwise, autoreleased objects accumulate and your memory footprint grows. If, however, your detached thread does not make Cocoa calls, you do not need to create an autorelease pool.
Note
If you are creating secondary threads using the POSIX thread APIs instead of NSThread objects, you cannot use Cocoa, including NSAutoreleasePool, unless Cocoa is in multithreading mode. Cocoa enters multithreading mode only after detaching its first NSThread object. To use Cocoa on secondary POSIX threads, your application must first detach at least one NSThread object, which can immediately exit. You can test whether Cocoa is in multithreading mode with the NSThread class method isMultiThreaded.
參考
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/
http://www.rzrgm.cn/CoderAlex/p/5232357.html
posted on 2016-08-18 15:08 ACM_Someone like you 閱讀(547) 評論(0) 收藏 舉報
浙公網安備 33010602011771號