release和autorelease區(qū)別:release只是把對象引用計數(shù)-1。autorelease實際上只是把release延遲調(diào)用了【autorelease會在對象真正使用結(jié)束時候才做引用計數(shù)-1】,系統(tǒng)只是把對象放入了autoreleasepool中,當(dāng)pool釋放時,該pool中所有對象就會被調(diào)用release。
autoreleasepool并不是程序退出時才將里面對象release。對于每一個runloop,系統(tǒng)會隱式的創(chuàng)建一個autoreleasepool構(gòu)成一個像callstack一樣的棧式結(jié)構(gòu),在runloop結(jié)束時,當(dāng)前棧頂?shù)膔elease pool會被銷毀,這個pool里面每個對象也會被release。
原理:NSAutoreleasepool實際上是個對象引用計數(shù)自動處理器。ARC中,系統(tǒng)自動幫我們嵌入.當(dāng)pool釋放時,該pool中的所有對象就會被調(diào)用release。
ARC年代,系統(tǒng)自動管理自己的autoreleasepool,runloop就是iOS中的消息循環(huán)機制,當(dāng)一個runloop結(jié)束時系統(tǒng)才會清理掉被autorelease處理過的對象。。
所以,如果循環(huán)創(chuàng)建了很多臨時對象,可以在循環(huán)中使用自動釋放池block,下次迭代前處理這些對象,再循環(huán)中使用自動釋放池block,有助于進減少內(nèi)存占用。
for (NSURL *url in urls) {
@autoreleasepool {
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error];
}
}每個@autoreleasepool結(jié)束時,里面的臨時變量就會回收,內(nèi)存使用更加合理。
autoreleasepool何時釋放:(1)手動釋放autoreleasepool(2)runloop結(jié)束后自動釋放。
手動創(chuàng)建:NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;
ARC下,不能調(diào)用autorelease,可以使用@autoreleasepool{}