52个有效方法(29) - 理解引用计数
2018-09-06 本文已影响6人
SkyMing一C
-
Objective-C语言使用引用计数来管理内存,每个对象都有个可以递增或递减的计数器。
-
如果想使某个对象继续存活,那就递增其引用计数;用完了之后,就递减其引用计数。
-
计数变为0,就表示没人关注此对象了,就可以把它销毁。
引用计数工作原理
-
NSObject协议声明了下面三个方法用于操作计数器,以递增或递减其值。
-
retain 递增保留计数。
-
release 递减保留计数。
-
autorelease 待稍后清理“自动释放池”(autorelease pool)时,再递减保留计数。
-
-
对象创建出来时,其保留计数至少为1。
-
对象如果持有指向其他对象的强引用(strong reference),那么前者就“拥有”(own)后者。对象想令其所引用的那些对象继续存活,就可将其“保留”。等用完了之后,再释放。
-
为避免在不经意间使用了无效对象,一般调用完release之后都会清空指针。这就能保证不会出现“悬挂指针”(dangling pointer)。
属性存取方法中的内存管理
- 若属性为“strong关系”(strong relationship),则设置的属性值会保留
- (void)setFoo:(id)foo
{
[foo retain];
[_foo release];
_foo = foo;
//此方法将保留新值并释放旧值,然后更新实例变量,令其指向新值。顺序很重要。
}
自动释放池
-
调用autorelease会在稍后递减计数,通常是在下一次“时间循环”(event loop)时递减,不过也可能执行的更早些。
-
调用autorelease可以保证对象在跨越“方法调用边界”(method call boundary)后一定存活。
保留环
- 通常采用“弱引用”(weak reference)或是"从外界命令循环中的某个对象不再保留另一个对象"方法打破保留环,从而避免内存泄露。
- 代理使用
weak
关键字修饰。weak会在销毁delegate指向的对象后,delegate置为nil,这样就没有野指针产生。如果用assign
关键字修饰,也有weak的功效。但assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针。
要点
-
引用计数机制通过可以递增递减的计数器来管理内存。对象创建好之后,其保留计数至少为1.若保留计数为正,则对象继续存活。当保留计数将为0时,对象就被销毁了。
-
在对象生命周期中,其余对象通过应用来保留或释放此对象。保留与释放操作分别会递增及递减保留计数。