返回

objc4源码解析:release方法剖析

IOS

objc4中release方法的内部机制

在objective-c中,开发人员负责管理对象的生存周期,这可以通过引用计数来实现。引用计数的增加和减少分别通过retain和release方法来完成。release方法对对象的引用计数进行减1操作,当引用计数为0时,对象被释放。

objc4源码解析

release方法

objc4中release方法的实现位于objc4-runtime-objc.mm,源码如下:

(oneway void)release {
    this->rootRelease();
}

void objc_object::rootRelease() {
    atomic_fetch_sub_explicit(&weakCount, 1, memory_order_acquire);
    if (weakCount == 0) {
        _objc_rootRelease(this);
    }
}

方法分解

  1. atomic_fetch_sub_explicit(&weakCount, 1, memory_order_acquire) :原子地将对象的weakCount减1,该操作使用memory_order_acquire内存屏障,确保引用计数的减操作在其他线程可见。

  2. if (weakCount == 0) :判断weakCount是否为0,当weakCount为0时,说明对象不再被引用,可以被释放。

  3. _objc_rootRelease(this) :调用_objc_rootRelease方法释放对象。

_objc_rootRelease方法

_objc_rootRelease方法位于objc4-runtime-objc.mm,源码如下:

void _objc_rootRelease(id obj) {
    auto deleter = obj->_getNonGCAndZeroingDeleter();
    if (deleter) {
        deleter(obj, obj->cls);
    } else if (!obj->_isRecorded()) {
        obj->cls->setIsa(nullptr);
    }
    free(obj);
}

方法分解

  1. auto deleter = obj->_getNonGCAndZeroingDeleter() :获取对象的非GC和置零的析构器。

  2. if (deleter) :如果析构器不为空,则调用析构器释放对象。

  3. else if (!obj->_isRecorded()) :如果对象未被记录,则将对象的isa指针置空。

  4. free(obj) :释放对象的内存。

总结

objc4中的release方法通过原子地减少对象的weakCount,当weakCount为0时,调用_objc_rootRelease方法释放对象。_objc_rootRelease方法会根据对象的类型(是否为GC对象)选择不同的释放策略,最终释放对象的内存。通过理解release方法的内部实现,开发者可以更深入地掌握objective-c中的内存管理机制。

常见问题解答

  1. 什么是引用计数?

引用计数是一种管理对象生命周期的技术,它记录了有多少变量引用了该对象。当变量不再引用该对象时,引用计数就会减少。当引用计数为0时,对象将被释放。

  1. retain方法的作用是什么?

retain方法将对象的引用计数增加1,表示又有了一个变量引用了该对象。

  1. release方法的作用是什么?

release方法将对象的引用计数减少1,表示又少了一个变量引用了该对象。当引用计数为0时,对象将被释放。

  1. 为什么需要手动管理引用计数?

objective-c是一种手动内存管理的语言,这意味着开发人员负责管理对象的生存周期。如果不手动管理引用计数,可能会出现内存泄漏或野指针错误。

  1. 如何在objective-c中避免内存泄漏?

避免内存泄漏的最佳方法是遵循引用计数规则,即在不再需要对象时释放它。同时,还可以使用ARC(自动引用计数)来管理对象的生存周期,它可以自动释放对象,从而避免内存泄漏。