objc4源码解析:release方法剖析
2023-09-21 08:03:45
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);
}
}
方法分解
-
atomic_fetch_sub_explicit(&weakCount, 1, memory_order_acquire) :原子地将对象的weakCount减1,该操作使用memory_order_acquire内存屏障,确保引用计数的减操作在其他线程可见。
-
if (weakCount == 0) :判断weakCount是否为0,当weakCount为0时,说明对象不再被引用,可以被释放。
-
_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);
}
方法分解
-
auto deleter = obj->_getNonGCAndZeroingDeleter() :获取对象的非GC和置零的析构器。
-
if (deleter) :如果析构器不为空,则调用析构器释放对象。
-
else if (!obj->_isRecorded()) :如果对象未被记录,则将对象的isa指针置空。
-
free(obj) :释放对象的内存。
总结
objc4中的release方法通过原子地减少对象的weakCount,当weakCount为0时,调用_objc_rootRelease方法释放对象。_objc_rootRelease方法会根据对象的类型(是否为GC对象)选择不同的释放策略,最终释放对象的内存。通过理解release方法的内部实现,开发者可以更深入地掌握objective-c中的内存管理机制。
常见问题解答
- 什么是引用计数?
引用计数是一种管理对象生命周期的技术,它记录了有多少变量引用了该对象。当变量不再引用该对象时,引用计数就会减少。当引用计数为0时,对象将被释放。
- retain方法的作用是什么?
retain方法将对象的引用计数增加1,表示又有了一个变量引用了该对象。
- release方法的作用是什么?
release方法将对象的引用计数减少1,表示又少了一个变量引用了该对象。当引用计数为0时,对象将被释放。
- 为什么需要手动管理引用计数?
objective-c是一种手动内存管理的语言,这意味着开发人员负责管理对象的生存周期。如果不手动管理引用计数,可能会出现内存泄漏或野指针错误。
- 如何在objective-c中避免内存泄漏?
避免内存泄漏的最佳方法是遵循引用计数规则,即在不再需要对象时释放它。同时,还可以使用ARC(自动引用计数)来管理对象的生存周期,它可以自动释放对象,从而避免内存泄漏。