什么是引用计数
原理
当我们创建一个新对象的时候,它的引用计数为1;当有一个新的指针指向这个对象时,我们将其引用计数加1;当这个指针不再指向这个对象的时候,我们将其引用计数减1;当这个对象的引用计数为0的时候,说明这个对象不再被如何指针指向,这个时候就可以销毁对象,回收内存。
对应的消息发送方法如下
- 当对象被创建(通过 alloc、new 或 copy 等方法)时,其引用计数初始值为1
- 给对象发送 retain 消息,其引用计数加1
- 给对象发送 release 消息,其引用计数减1
- 当对象引用计数归0时,Objective-C 給对象发送 dealloc 消息销毁对象
添加编译参数
新建一个工程,由于现在的工程默认开启自动引用计数(Automatic Reference Count),我们需要修改工程设置,启动手工管理引用计数的模式。
在 Target 的 Build Phases 中给 AppDelegate.m 加上 -fno-objc-arc 的编译参数。
添加代码
在 AppDelegate.m 中添加以下代码,通过 Log 可以看到引用计数的变化
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSObject *object = [[NSObject alloc] init];
NSLog(@"Reference Count = %lu", (unsigned long)[object retainCount]);
NSObject *anotherObject = [object retain];
NSLog(@"Reference Count = %lu", (unsigned long)[object retainCount]);
[anotherObject release];
NSLog(@"Reference Count = %lu", (unsigned long)[object retainCount]);
[object release];
return YES;
}
运行结果如下图
不要向已释放的对象发送消息
在上面的代码中的 object 对象释放后添加以下代码
NSLog(@"Reference Count = %lu", (unsigned long)[object retainCount]);
运行后得到结果会发现获取到的引用计数为1,为什么不是0呢?
因为对引用计数为1的对象 release 时,系统知道该对象即将被回收,就不会再对该对象的引用计数进行减1操作,这样可以增加对象回收的效率,加速对象的回收。
对已释放的对象发送消息是不可取的,因为对象的内存已被回收,如果发送消息时,该内存已经被其他对象使用了,得到的结果是无法确定的,有可能造成程序异常崩溃。
最后
本人为iOS开发新手一枚,写的不好的或写错的地方,希望各位大侠能帮忙指正。
各位大侠,如果觉得对自己有点用的,欢迎点个赞,也欢迎大家关注我( Github / 简书 / 微博 / Instagram / 知乎)
谢谢观看此文。