美文网首页
Autorelease Pool

Autorelease Pool

作者: xinghunMeng | 来源:发表于2017-02-12 08:35 被阅读0次

    自动释放池是iOS中的内存回收机制,能够延迟对象的释放。当池中的对象超出作用域后并不会立即被释放,等待自动释放池销毁后,自动释放池会像池中的所有对象发送release消息(如果你给一个对象多次发送autorelease消息,那么当自动释放池销毁时,这个对象也会收到同样数目的release消息),释放池中的对象。

    加入自动释放池

    • MRC
    NSObject *obj = [[NSObject alloc]init];
    //需调用autorelease方法加入自动释放池
    [obj autorelease];
    //手动释放
    [obj release];
    
    • ARC
      dog对象加入到block自动释放池,在出大括号后自动释放池销毁,向池中对象发送release消息,销毁了dog对象。
    @autoreleasepool {
    Dog *dog = [[Dog alloc]init];
    NSLog(@"分割线----------------");
    }
    NSLog(@"自动释放池销毁");
    //执行结果
    分割线----------------
    dog 销毁了
    自动释放池已销毁
    

    自动释放池的释放

    对于手动创建的局部释放池在大括号结束后就会被释放(如上dog所在的是释放池),而每一次消息循环开始会创建一个全局释放池,而RunLoop释放池会等一次消息循环结束的时候释放。可以理解为在程序持续执行的时候不会销毁释放池,直到产生屏幕旋转,等待用户输入等事件,消息循环结束,销毁释放池,重新开始循环,创建全局释放池。
    如下创建的str很多,而系统的类方法stringWithFormat:本质上是调用了alloc + initWithFormat: + autorelease,新建的str对象并不会立即释放,必须等到消息循环结束,造成内存飚升。

    for (int i = 0; i < 10000000; i++) {
    //系统类方法,会将创建的对象加入系统自动释放池
    NSString *str = [NSString stringWithFormat:@"hello -%d", i];
    //系统对象方法不会将创建的对象加入系统自动释放池,因此每次循环对象都会释放。
    //NSString *str =[[NSString alloc]initWithFormat:@"hello -%d",i];
    str = [str stringByAppendingString:@" - world"];
    };
    

    在循环内加入自动释放池,即可控制对象的释放。

    for (int i = 0; i < 10000000; i++) {
    @autoreleasepool {
    NSString *str = [NSString stringWithFormat:@"hello -%d", i];
    str = [str stringByAppendingString:@" - world"];
    }
    };
    

    自动释放池应用场景

    • 如果你编写的程序不是基于 UI 框架的,比如说命令行工具(不会自动创建外层的全局自动释放池);
    • 如果你编写的循环中创建了大量的临时对象,如上;
    • 如果你创建了一个辅助线程,主线程会自动创建外层的自动释放池。

    PS: I am xinghun who is on the road.

    相关文章

      网友评论

          本文标题:Autorelease Pool

          本文链接:https://www.haomeiwen.com/subject/tzfaittx.html