前二天去某土豪创业公司面试被问到了内存管理的一些问题,面试官提到了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。
![Paste_Image.png](https://img.haomeiwen.com/i1796297/
![](https://img.haomeiwen.com/i1796297/383df77f201aeec7.png)
再看看加了@autoreleasepool后:
for (int i=0;i<100000;i++) {
@autoreleasepool {
UIImage *image = [UIImage imageNamed:@"pic"];
}
}
运行结果如下:
![](https://img.haomeiwen.com/i1796297/574a5309a6c30c07.png)
可以看到内存并没有出现疯长的情况,因为@autoreleasepool的作用,每次循环结束后,局部变量会立刻释放。
网友评论