前二天去某土豪創業公司面試被問到了內存管理的一些問題,面試官提到了autoreleasepool的問題,但是由于項目中從來沒有用過,當時的回答全是憑自己的想象,結果也就可想而知了。
回來后查閱了很多資料,發現autoreleasepool和runloop有密切的關系。
下面舉一下面試官的問題:
{
NSString *str = @"a";
}
給一段上述代碼,問str對象什么時候釋放,我回答的是函數體執行完后就釋放了,面試官反問是么,我說是吧(感覺到自己是錯的,但是一直用ARC,這快真的從來沒有在意過TOT)。
然后面試官又問,下面這么寫呢。我說也是函數體執行完后釋放吧(已經慌了,要GG)。面試官笑著說:那你這么說寫不寫豈不是都一樣?
{
@autoreleasepool {
NSString *str = @"a"
}
今天找時間再次看了一下autoreleasepool的原理,發現提到了runloop,雖然之前看過runloop,但是看得并不是很仔細。于是又重新看了一遍,發現了一些之前錯誤的認識,同時也知道了autoreleasepool內對象的時機,其實和runloop的執行時機有關,和函數體沒有半毛錢關系。
接下來就有疑問了,為什么要在函數體內又寫一次@autoreleasepool。查閱資料后,發現了這樣有利于局部變量立刻釋放,于是自己做了一個小測試:
for (int i=0;i<100000;i++) {
UIImage *image = [UIImage imageNamed:@"pic"];
}
運行結果如下,可以看到內存直接瘋長,最高達到了200M。
 {
@autoreleasepool {
UIImage *image = [UIImage imageNamed:@"pic"];
}
}
運行結果如下:
Paste_Image.png
可以看到內存并沒有出現瘋長的情況,因為@autoreleasepool的作用,每次循環結束后,局部變量會立刻釋放。