常见的面试题:如下代码存在什么样的问题?应该如何改进?面试
for (int i = 0; i < 100000; i++) {oop NSString *str = @"abc";spa str = [str stringByAppendingString:@"xyz"];对象 }blog |
利用leaks查看内存泄漏状况内存
可知:NSString对象str并无立刻被释放,在内存中会同时存在100000个NSString对象,形成内存急增,等100000for循环结束才释放作用域
改进:string
for (int i = 0; i < 100000; i++) {for循环 @autoreleasepool {table NSString *str = @"abc"; str = [str stringByAppendingString:@"xyz"]; } } |
或者(注意NSAutoreleasePool ARC下不可用,必须将工程改成MRC)
for (int i = 0; i < 100000; i++) { //建立一个自动释放池 NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSString *str = @"abc"; str = [str stringByAppendingString:@"xyz"]; //自动释放池被销毁或耗尽,会向自动释放池中的全部对象发送release消息 [pool drain]; } |
利用leaks查看内存泄漏状况
可知:不会形成内存急增,每次for循环结束NSString对象str都会释放,在内存中会只存在1个NSString对象str
自动释放池(autoreleasepool)的工做原理:
//@autoreleasepool {}中的代码 void *context = objc_autoreleasePoolPush(); //当前runloop迭代结束时进行pop操做 objc_autoreleasePoolPop(context); |
autoreleasepool是个栈结构,对象加入池子时其实质是进行入栈Push操做,释放对象时其实质是进行出栈Pop操做。
标记为autorelease的对象在出了做用域范围后,会被添加到最近一次建立的自动释放池中,当前runloop迭代结束时,会向自动释放池中的全部对象发送release消息,当池子里的全部对象引用计数都为0
时该池子被销毁