美文网首页iOS开发实用技巧iOS日常须知
IOS内存管理--自动释放池的实现原理

IOS内存管理--自动释放池的实现原理

作者: 昵称nickName | 来源:发表于2018-08-07 09:58 被阅读303次
    1. 在主线程的 NSRunLoop 对象(在系统级别的其他线程中应该也是如此,比如通过 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 获取到的线程)的每个 event loop 开始前,系统会自动创建一个 autoreleasepool ,并在 event loop 结束时 drain 。我们上面提到的场景 1 中创建的 autoreleased 对象就是被系统添加到了这个自动创建的 autoreleasepool 中,并在这个 autoreleasepool 被 drain 时得到释放。
    2. 每一个线程都会维护自己的 autoreleasepool 堆栈。换句话说 autoreleasepool 是与线程紧密相关的,每一个 autoreleasepool 只对应一个线程。
    
    1). 只有在自动释放池中调用了对象的autorelease方法,这个对象才会被存储到这个自动释放池之中.
        如果只是将对象的创建代码写在自动释放之中,而没有调用对象的autorelease方法.是不会将这个对象存储到这个自动释放池之中的.
    
    2). 对象的创建可以在自动释放池的外面,在自动释放池之中,调用对象的autorelease方法,就可以将这个对象存储到这个自动释放池之中.
        将1个对象存储到自动释放池中,最重要的步骤
        调用对象的autorelease方法,这句代码一定要放在池子中.
    
    3). 当自动释放池结束的时候.仅仅是对存储在自动释放池中的对象发送1条release消息 而不是销毁对象.
    
    4). 如果在自动释放池中,调用同1个对象的autorelease方法多次.就会将对象存储多次到自动释放池之中.
    在自动释放池结束的时候.会为对象发送多条release消息.那么这个时候就会出现僵尸对象错误.
    所以,1个自动释放池之中,只autorelease1次,只将这个对象放1次, 否则就会出现僵尸对象错误.
    
    5). 如果在自动释放池中,调用了存储到自动释放中的对象的release方法.
    在自动释放池结束的时候,还会再调用对象的release方法.
    这个时候就有有可能会造成野指针操作.
    
    也可以调用存储在自动释放池中的对象的retain方法.
    
    
    6). 将对象存储到自动释放池,并不会使对象的引用计数器+1
    所以其好处就是:创建对象将对象存储在自动释放池,就不需要在写个release了.
    
    7).  自动释放池可以嵌套.
    调用对象的autorelease方法,会讲对象加入到当前自动释放池之中
    只有在当前自动释放池结束的时候才会像对象发送release消息.
    

    默认主线的运行循环(runloop)是开启的,子线程的运行循环(runloop)默认是不开启的,也就意味着子线程中不会创建autoreleasepool,所以需要我们自己在子线程中创建一个自动释放池。(子线程里面使用的类方法都是autorelease,就会没有池子可释放,也就意味着后面没有办法进行释放,造成内存泄漏。)

    相关文章

      网友评论

        本文标题:IOS内存管理--自动释放池的实现原理

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