@autoreleasepool 用法

- (void)dealloc {
 #ifdef DEBUG
    // 确定是不是被释放
    __weak AKKAAEManagedValue * weakvalue = nil;
    @autoreleasepool {
        weakvalue = _value;
        self.value = nil;
    }
    if (weakvalue) {
        NSLog(@"AKKAAEArray value leaked: %@",weakvalue);
        weakvalue.releaseBlock = nil;
    }
 #else
    @autoreleasepool {
        self.value = nil;
    }
 #endif
}

****MRC**** 与 ****ARC****
****MRC****(****Mannul Reference Counting****)********和****ARC(Automatic Reference Counting)****,分别对应着手动引用计数和自动引用计数。
对!是计数,不是“****GC****、垃圾回收********”什么的,就是说,在****Objective-C****的开发中,****ARC****不代表像****Java****那样有****GC****做垃圾回收,所以本质上还是要“手动”管理内存的。也就是说,我们在****ARC****环境下写的代码,不用自己手动插入“****retain****、****release****这些消息********”,****ARC****会在编译时为我们在合适的位置插入,释放不必要的内存。
而****@autoreleasepool****就跟对象的****release****密切相关。

@autoreleasepool 干了啥

在****MRC****时代,如果我们想先****retain****一个对象,但是并不知道在什么时候可以****release****它,我们可以像下面这么做:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString* str = [[[NSString alloc] initWithString:@"tutuge"] autorelease];
//use str...
[pool release];
//str is released

就是说,我们可以在创建对象的时候给对象发送“****autorelease****”消息,然后当****NSAutoreleasePool****结束的时候,“标记过”****autorelease****的对象都会被“****release****”掉,也就是会被释放掉。
但是在ARC时代,我们不用手动发送****autorelease****消息,ARC会自动帮我们加。而这个时候,****@autoreleasepool****做的事情,跟****NSAutoreleasePool****就一模一样了。

什么时候用@autoreleasepool

根据****Apple****的文档********,使用场景如下:

  • 写基于命令行的的程序时,就是没有UI框架,如AppKit等Cocoa框架时。
  • 写循环,循环里面包含了大量临时创建的对象。(本文的例子)
  • 创建了新的线程。(非Cocoa程序创建线程时才需要)
  • 长时间在后台运行的任务。

利用@autoreleasepool优化循环

利用****@autoreleasepool****优化循环的内存占用,我觉得最有用的一点,下面就说说这个点。如下面的循环,次数非常多,而且循环体里面的对象都是临时创建使用的,就可以用****@autoreleasepool****包起来,让每次循环结束时,可以及时的释放临时对象的内存。

//来自Apple文档,见参考
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
    @autoreleasepool {
        NSError *error;
        NSString *fileContents = [NSString stringWithContentsOfURL:url                                       encoding:NSUTF8StringEncoding error:&error];

        /* Process the string, creating and autoreleasing more objects. */

    }
}

这么做的效果是极其显著地,就如本文最开始的图一样,可以自己把示例工程下回来运行下试试~
总结
****@autoreleasepool****看起来很不“起眼”,平常开发很容易就忽略它了,但是仔细一看,确如此有用~

你可能感兴趣的:(@autoreleasepool 用法)