自動(dòng)釋放池什么時(shí)候創(chuàng)建,什么時(shí)候銷毀?
? ? ? ? 每一次運(yùn)行循環(huán)執(zhí)行后,也就是每當(dāng)事件被觸發(fā)時(shí)都會(huì)創(chuàng)建自動(dòng)釋放池宽菜。在程序執(zhí)行的過(guò)程中,所有autorelease的對(duì)象在出了作用域之后會(huì)被添加到最近創(chuàng)建的自動(dòng)釋放池中竿报。運(yùn)行循環(huán)結(jié)束前會(huì)釋放自動(dòng)釋放池铅乡,還有池子滿了也會(huì)銷毀。
工作原理
? ? ? ?自動(dòng)釋放池被銷毀或耗盡時(shí)會(huì)向池中的所有對(duì)象發(fā)送release消息烈菌,釋放所有autorelease對(duì)象阵幸。
示例:
int largeNumber = 2 * 1024 * 1024;
/*? 問(wèn)題:(1)以下代碼是否存在問(wèn)題?(2)如果有僧界,怎么修改侨嘀?
網(wǎng)上的解決辦法:
1)@autoreleasepool 放在外面臭挽,保證循環(huán)之后釋放循環(huán)中的自動(dòng)釋放對(duì)象捂襟,適用于創(chuàng)建對(duì)象次數(shù)不太大的循環(huán)。
2)@autoreleasepool 放在內(nèi)部欢峰,每一次循環(huán)之后葬荷,都傾倒一次自動(dòng)釋放池,內(nèi)存管理是最好的纽帖,但是性能不好宠漩!適用于創(chuàng)建對(duì)象次數(shù)很大的循環(huán)。
*/
for (int i = 0; i < largeNumber; i++) {
? ? @autoreleasepool {
? ? ? ? ?NSString *str = [NSString stringWithFormat:@"Hello "];
? ? ? ? ?str = [str uppercaseString];
? ? ? ? ?str = [str stringByAppendingString:@" - World"];
? ?}
}
注意:每一個(gè)線程都有一個(gè)RunLoop懊直,但是只有主線程的RunLoop(運(yùn)行循環(huán))會(huì)默認(rèn)啟動(dòng)扒吁。也就意味著不會(huì)自動(dòng)創(chuàng)建自動(dòng)釋放池,子線程里面autorelease的對(duì)象也就意味著沒(méi)有池子可存放室囊,也就意味著在后面無(wú)法進(jìn)行釋放雕崩,造成內(nèi)存泄露魁索。在使用NSThread做多線程開(kāi)發(fā)時(shí),需要在線程調(diào)度方法中手動(dòng)添加自動(dòng)釋放池盼铁。@autorelease{? // 執(zhí)行代碼? }
如果沒(méi)有使用alloc new copy retain 方法而創(chuàng)建了對(duì)象粗蔚,則內(nèi)部全是使用了autorelease方法。所以使用自動(dòng)釋放池能對(duì)這些對(duì)象進(jìn)行及時(shí)釋放饶火。