美文网首页学习准备内存RunLoop
autoreleasepool的使用场景和原理

autoreleasepool的使用场景和原理

作者: natewang | 来源:发表于2018-07-29 11:09 被阅读263次

    autoreleasepool 贯穿app的整个周期。

    int main(int argc, char * argv[]) {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    

    autoreleasepool 是一种机制,实现了放入其中的对象,可以再生命周期结束后自动进行释放。
    AutoreleasePoolPage 以双向链表组合,实现autoreleasepool;


    image.png

    这个 id *next 存放新进来的对象。


    image.png
    void *context = objc_autoreleasePoolPush();
    // {}中的代码
    objc_autoreleasePoolPop(context);
    

    当调用objc_autoreleasePoolPush()时,会在栈中加入一个哨兵。调用对应的objc_autoreleasePoolPop,就会释放中间加入的所有对象。


    image.png

    runloop相关

    App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,其回调都是 _wrapRunLoopWithAutoreleasePoolHandler()。
    第一个 Observer 监视的事件是 Entry(即将进入Loop),其回调内会调用 _objc_autoreleasePoolPush() 创建自动释放池。其 order 是-2147483647,优先级最高,保证创建释放池发生在其他所有回调之前。
    第二个 Observer 监视了两个事件: BeforeWaiting(准备进入休眠) 时调用_objc_autoreleasePoolPop() 和 _objc_autoreleasePoolPush() 释放旧的池并创建新池;Exit(即将退出Loop) 时调用 _objc_autoreleasePoolPop() 来释放自动释放池。这个 Observer 的 order 是 2147483647,优先级最低,保证其释放池子发生在其他所有回调之后。
    在主线程执行的代码,通常是写在诸如事件回调、Timer回调内的。这些回调会被 RunLoop 创建好的 AutoreleasePool 环绕着,所以不会出现内存泄漏,开发者也不必显示创建 Pool 了。

    参考
    https://blog.sunnyxx.com/2014/10/15/behind-autorelease/
    https://draveness.me/autoreleasepool#AutoreleasePoolPage
    https://juejin.im/post/5a687e356fb9a01c94060620

    相关文章

      网友评论

        本文标题:autoreleasepool的使用场景和原理

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