以下情景均為 ARC 環(huán)境
情景 1:
for ( int i = 0; i < 10000000; i++) {
NSString *str = [[NSString alloc] initWithFormat:@"dang %d", i];
}
分析:str 的默認變量內(nèi)存管理語義是 __strong,在每次循環(huán)之后泽腮,會自動 release 掉。
情景 2:
for ( int i = 0; i < 10000000; i++) {
NSString *str = [NSString stringWithFormat:@"dang %d", i];
}
分析:內(nèi)存暴漲說明沒有調(diào)用 objc_retainAutoreleasedReturnValue ,也就是說膏执,stringWithFormat:返回的是一個 autorelease 對象鼠哥。而此時 runloop 由于 for 循環(huán)沒有結(jié)束一直處于醒著的狀態(tài)熟菲,直到 for 循環(huán)結(jié)束才會傾倒自動釋放池看政,在這過程中產(chǎn)生的大量的 autorelease 對象使得內(nèi)存暴漲。
情景 3:
for ( int i = 0; i < 10000000; i++) {
@autoreleasepool {
NSString *str = [NSString stringWithFormat:@"dang %d", i];
}
}
分析:為了解決情景 2 中的問題抄罕,每次循環(huán)時創(chuàng)建一個自動釋放池允蚣,臨時對象可以及時 release 掉,就不會使得內(nèi)存暴漲了呆贿。
總結(jié):
什么時候使用自動釋放池嚷兔?
在一些博客中說的是在 loop 中 NSData 轉(zhuǎn)為 UIImage 時,在一些技術(shù)群中也有不少人是這么回答的榨崩。其實這只是使用自動釋放池的一種情況谴垫,歸根結(jié)底是 在 loop 中通過非 alloc/new/copy/mutableCopy 方法創(chuàng)建對象 時使用,例如[NSMutableArray array];
母蛛、[UIImage imageWithData:data];
翩剪,這些方法創(chuàng)建的 autorelease 對象需要放在 pool 中及時釋放掉。