常見的面試題:如下代碼存在什麼樣的問題?應該如何改進?面試
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
時該池子被銷燬