首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

AutoreleasePool从入门到放弃(5)

AutoreleasePool从入门到放弃(5)

autoreleaseNoPage(id obj)

    static __attribute__((noinline)) id *autoreleaseNoPage(id obj)
        {
            // "No page" could mean no pool has been pushed
            // or an empty placeholder pool has been pushed and has no contents yet
            assert(!hotPage());
     
            bool pushExtraBoundary = false;
            if (haveEmptyPoolPlaceholder()) {
                // We are pushing a second pool over the empty placeholder pool
                // or pushing the first object into the empty placeholder pool.
                // Before doing that, push a pool boundary on behalf of the pool
                // that is currently represented by the empty placeholder.
                pushExtraBoundary = true;
            }
            else if (obj != POOL_BOUNDARY  &&  DebugMissingPools) {
                // We are pushing an object with no pool in place,
                // and no-pool debugging was requested by environment.
                _objc_inform("MISSING POOLS: (%p) Object %p of class %s "
                             "autoreleased with no pool in place - "
                             "just leaking - break on "
                             "objc_autoreleaseNoPool() to debug",
                             pthread_self(), (void*)obj, object_getClassName(obj));
                objc_autoreleaseNoPool(obj);
                return nil;
            }
            else if (obj == POOL_BOUNDARY  &&  !DebugPoolAllocation) {
                // We are pushing a pool with no pool in place,
                // and alloc-per-pool debugging was not requested.
                // Install and return the empty pool placeholder.
                return setEmptyPoolPlaceholder();
            }
     
            // We are pushing an object or a non-placeholder'd pool.
     
            // Install the first page.
            AutoreleasePoolPage *page = new AutoreleasePoolPage(nil);
            setHotPage(page);
            
            // Push a boundary on behalf of the previously-placeholder'd pool.
            if (pushExtraBoundary) {
                page->add(POOL_BOUNDARY);
            }
            
            // Push the requested object or pool.
            return page->add(obj);
        }

    如果第一次向AutoreleasePool入栈对象或者在一个空的AutoreleasePool基础上内嵌另外一个AutoreleasePool时设置需入栈POOL_BOUNDARY标志位(POOL_BOUNDARY是每个不同AutoreleasePool之间的分隔符)

    如果在没有AutoreleasePool的基础上入栈对象则Log用户存在内存泄漏

    如果入栈对象为POOL_BOUNDARY并且在非DEBUG模式下则设置空AutoreleasePool标志位

创建AutoreleasePoolPage分页并设置为当前分页,根据上述情况判断是否需要插入AutoreleasePool边界标识。最后才入栈所需的对象。
autoreleaseFast(id obj)

    static inline id *autoreleaseFast(id obj)
        {
            AutoreleasePoolPage *page = hotPage();
            if (page && !page->full()) {
                return page->add(obj);
            } else if (page) {
                return autoreleaseFullPage(obj, page);
            } else {
                return autoreleaseNoPage(obj);
            }
        }

    当前存在AutoreleasePoolPage并且AutoreleasePoolPage未满
        入栈对象

    当前存在AutoreleasePoolPage但AutoreleasePoolPage已满
        调用autoreleaseFullPage函数查找未满的子AutoreleasePoolPage进行对象入栈,如果未查找到则创建新的子AutoreleasePoolPage再进行入栈操作

    当前不存在AutoreleasePoolPage则调用autoreleaseNoPage函数创建新的autoreleaseNoPage再进行入栈操作

objc_autoreleasePoolPop(void *ctxt)

    void objc_autoreleasePoolPop(void *ctxt)
    {
        AutoreleasePoolPage::pop(ctxt);
    }
返回列表