Re: [quiz] NSImage's leak
※ 引述《anpig (Andrew)》之銘言:
: 不好意思把舊文搬出來討論。
: 最近又重新K了一次cocoa memory management
: 就想到你在這邊貼的文章
: 剛剛重看完詳解之後有個疑問,就是你說在loop裡放autorelease pool
: 看來用意是要release在loop裡allocate NSImage時
: 所附帶產生出需要autorelease的物件
: 是否是因為這些物件在產生NSImage物件過程中用了[xxx autorelease];
: 但是非得等到loop這個scope結束才會clean up,而且會clean up的原因
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
到這句話為止是正確的!
: 不是retain count為0,而是因為成為garbage。以上的理解正確嗎?
這邊不正確。Objective-C 1.0 並沒有 garbage collection,只要有東西
變成 garbage (已經沒有指標指向它) 就沒救了,再也收不回來。
autorelease 沒那麼神奇/複雜,他只是一個簡單漂亮的實作:
當遇到 [xxx autorelease] 的時候,並不減少 xxx 的 retainCount,
而是讓「最靠近」的 NSAutoreleasePool 去記錄 xxx 收了多少次 auto-
release,等到那個 NSAutoreleasePool 本身 dealloc 的時候,就對所有
記錄下來的物件送「剛剛記錄下來那麼多次」 release。
所以這個時候,retainCount 也是會變成 0 的。
也就是說,[xxx autorelease] 可以想成「延遲 release」。
延遲到什麼時候?延遲到「最靠近的 NSAutoreleasePool」deallocated 的
時候。
: 所以這樣說來,在[img release];時候把這些附帶產生的物件的retain count
: 減至1,還需要一個autorelease pool來將他們的retain count減至0
: 是這樣嗎?
ㄟ?你這邊又說對了...
我猜猜看,可能是我題目只寫了部份程式碼造成你誤解了?
我題目好像這樣寫:
int i;
for (i = 0; i < 1000; i++) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSImage *img = [[NSImage alloc] initWithContentsOfFile:@”xxx.jpg”];
[img release];
[pool release];
}
你是不是以為這個直接包在 main() 裡面,四周都沒有 NSAutoreleasePool 呢?
如果是這樣那就是我題目沒有說明清楚,非常抱歉了...
在一般由 NSApplicationMain setup 起來的 Cocoa 程式裡,Main Run Loop
會幫你自動 create/destroy NSAutoreleasePool,所以只要你的 method
結束,跳回 Main Run Loop 的話,之前的 autoreleased object 就會被清掉。
我的題目是建設在這個假設之上,也就是說在該段程式碼所屬函式跑完以後,
裡面的 autorelease object 還是會 release 的,不會成為 garbage,只是
我想強調「因為 delay 到結束才 release,累積的東西太多造成效能低落」。
那如果是自己寫 main(), 例如寫純文字工具的時候,或者是在新的 Thread
開頭和結尾通常都要是 NSAutorelease 的 create/destory.
int main() {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
// ...[your code]...
[pool release];
return 0;
}
否則程式會出問題,因為 Cocoa Framework 裡面物件的使用是假設在任何
用到這些物件的時刻都有至少一個 NSAutoreleasePool,沒有的話會發生錯誤。
至於為什麼 NSImage 的生成會用到 autoreleased object 呢?我後來體會
到,這是一個保險的做法。在平行且多緒的環境下,若是沒有處理好 retain/
release,程式很可能會 crash。像是最基本的 accessor, 都很多人這樣寫:
- (id) someMember {
return [[_someMember retain] autorelease];
}
其實 Objective-C 真的很簡單,和 C 語言差不多,There's no magic.
他寫什麼就做什麼,卻能保持不錯的彈性和效率。ObjC 2.0 開始引進了一些
magic 了,例如 GC 和 atomic accessor... 離題自刪。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 59.112.163.47
→
11/28 14:39, , 1F
11/28 14:39, 1F
→
11/28 14:40, , 2F
11/28 14:40, 2F
討論串 (同標題文章)