iOS-内存管理

2022-02-08  本文已影响0人  yangfei02821

iOS里的内存管理

一、引用计数的存储

在64bit中,引用计数可以直接存储在优化过的isa指针extra_rc,如果引用计数器过大无法存储在isa中,会将isa中的has_sidetable_rc赋值为1,将引用计数存储在SideTable类中,以一个散列表形式保存

inline uintptr_t 
objc_object::rootRetainCount()
{
    if (isTaggedPointer()) return (uintptr_t)this;

    sidetable_lock();
    isa_t bits = LoadExclusive(&isa.bits);
    ClearExclusive(&isa.bits);
    /*
    nonpointer
    0,代表普通的指针,存储着Class、Meta-Class对象的内存地址
    1,代表优化过,使用位域存储更多的信息
     */
    if (bits.nonpointer) {
        // 从extra_rc中取出引用计数
        uintptr_t rc = 1 + bits.extra_rc;
        // 如果has_sidetable_rc为1,再从sidetable中取出引用计数
        if (bits.has_sidetable_rc) {
            rc += sidetable_getExtraRC_nolock();
        }
        sidetable_unlock();
        return rc;
    }

    sidetable_unlock();
    return sidetable_retainCount();
}

二、weak指针的实现原理

弱引用存在哈希表中,销毁时取出当前对象的弱引用表,把弱引用都清除掉。
弱引用表和isa存储不下的引用计数,都存放在SideTable类中


image.png
image.png

三、自动释放池的本质

autoreleasepool本质:

1、autoreleasepool其实也是一个结构体__AtAutoreleasePool,里边有一个构造函数和一个析构函数,
在大括号开始的位置调用他的构造函数,atautoreleasepoolobj = objc_autoreleasePoolPush();
大括号结束的时候调用他的析构函数,objc_autoreleasePoolPop(atautoreleasepoolobj);
在大括号中,调用了autorelease的对象最终都是通过AutoreleasePoolPage对象来管理的。
2、 AutoreleasePoolPage的结构


image.png

四、Runloop和Autorelease

Autorelease对象是在当前的runloop迭代结束时释放
当监听到进入runloop的时候,调用push函数
当休眠的时候,会将当前自动释放池pop,并且重新push
当退出runloop的时候,会调用pop函数

上一篇 下一篇

猜你喜欢

热点阅读