有些同学想测试当对象释放时,其 retainCount 是否变成了 0,他们的试验代码如下:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
NSObject*object = [[NSObjectalloc] init];
NSLog(@"Reference Count = %u", [object retainCount]);
[object release];
NSLog(@"Reference Count = %u", [object retainCount]);
returnYES;
}
不要向已经释放的对象发送消息:
但是,如果你真的这么实验,你得到的输出结果可能是以下这样:
Reference Count = 1
Reference Count = 1
我们注意到,最后一次输出,引用计数并没有变成 0。这是为什么呢?因为该对象的内存已经被回收,而我们向一个已经被回收的对象发了一个 retainCount 消息,所以它的输出结果应该是不确定的,如果该对象所占的内存被复用了,那么就有可能造成程序异常崩溃。
那为什么在这个对象被回收之后,这个不确定的值是 1 而不是 0 呢?这是因为当最后一次执行 release 时,系统知道马上就要回收内存了,就没有必要再将 retainCount 减 1 了,因为不管减不减 1,该对象都肯定会被回收,而对象被回收后,它的所有的内存区域,包括 retainCount 值也变得没有意义。不将这个值从 1 变成 0,可以减少一次内存的写操作,加速对象的回收。
拿Linux 文件系统举列,Linux 文件系统下删除一个文件,也不是真正的将文件的磁盘区域进行抹除操作,而只是删除该文件的索引节点号。这也和引用计数的内存回收方式类似,即回收时只做标记,并不抹除相关的数据。
ARC 下的内存管理问题
ARC 能够解决 iOS 开发中 90% 的内存管理问题,但是另外还有 10% 内存管理,是需要开发者自己处理的,这主要就是与底层 Core Foundation 对象交互的那部分,底层的 Core Foundation 对象由于不在 ARC 的管理下,所以需要自己维护这些对象的引用计数。
对于 ARC 盲目依赖的 iOS 新人们,由于不知道引用计数,他们的问题主要体现在:
过度使用 block 之后,无法解决循环引用问题。
遇到底层 Core Foundation 对象,需要自己手工管理它们的引用计数时,显得一筹莫展。
弱引用的实现原理
弱引用的实现原理是这样,系统对于每一个有弱引用的对象,都维护一个表来记录它所有的弱引用的指针地址。这样,当一个对象的引用计数为 0 时,系统就通过这张表,找到所有的弱引用指针,继而把它们都置成 nil。
在调试内存问题时,Instruments 工具可以很好地对我们进行辅助,善用 Instruments 可以节省我们大量的调试时间。
来源:本文为第三方转载,如有侵权请联系小编删除。