在OC的API中使用,readonly 和 copy聲明唤反,一般都是一個計算值,而在循環(huán)體中直接使用計算屬性則會大量消耗內(nèi)存彤侍,此時最好的解決辦法是在獲取某個計算屬性使用autoreleasepool來降低內(nèi)存峰值, 另外autorelease的值在循環(huán)中也會大量消耗內(nèi)存,當(dāng)然也可以使用autoreleasepool來降低內(nèi)存峰值盏阶;
下面兩個測試?yán)?/p>
低內(nèi)存:
while (true) {
NSString *a = [[NSString alloc] initWithFormat:@"test"];
}
高內(nèi)存:
while (true) {
NSString *a = [NSString stringWithFormat:@"test"];
}
當(dāng)然上面的高內(nèi)存版闻书,使用autoreleasepool可以降低內(nèi)存
while (true) {
@autoreleasepool {
NSString *a = [NSString stringWithFormat:@"test"];
}
}
對于每一個Runloop, 系統(tǒng)會隱式創(chuàng)建一個Autorelease pool魄眉, 這樣所有的release pool會構(gòu)成一個象CallStack一樣的一個棧式結(jié)構(gòu),在每一個Runloop結(jié)束時坑律,當(dāng)前棧頂?shù)腁utorelease pool會被銷毀,這樣這個pool里的每個Object會被release晃择。
一個UI事件、Timer call宫屠、 delegate call列疗、 都會是一個新的Runloop抵栈。
實際上對于 [NSString stringWithFormat:] 這類構(gòu)造函數(shù)返回的對象都是autorelease的告材。
autorelease pool來避免頻繁申請/釋放內(nèi)存(就是pool的作用了)竭讳!
總結(jié):
1.一定要注意Autorelease pool的生存周期,理解Runloop绢慢,避免在對象被釋放后使用。
2.[NSString stringWithFormat:]這類函數(shù)返回的對象是不需要再自己release的胰舆,它已經(jīng)被autorelease了, MRC下如果你想把它當(dāng)一個全局對象使用,那必須自己再retain缚窿, 釋放時再release。