问题描述
疑惑:1、内存管理:dealloc之后还能打印出retainCount = 1main方法中:person方法中覆写的dealloc方法和打印结果
2、 两个 category都只覆写了dealloc方法,用来输出验证Copy创建的对象release之后调用dealloc方法,但是在自动释放池释放对象时,又释放了一次为什么会释放两次啊?
3、使用类名方法创建对象,引用计数为2
问题解答
回答1:非一般的瓜子的答案是对的。
对NSMutableArray对象调用copy返回的是一个NSArray对象,所以在[array4 release]被调用时array4的dealloc方法被调用,输出NSArray dealloc。随后autoreleasepool被销毁,array3被释放,array3的dealloc方法被调用,因为NSMutableArray的dealloc方法中调用了[super dealloc],所以输出了随后的两句。
根据StackOverflow上的回答,这是因为NSArray是一个不可变对象,而由[NSArray array]或者[[NSArray alloc] init]生成的都是不可变的空数组,所以苹果默认所有不可变空数组的引用都指向一个唯一实例以进行优化,所以在[NSArray array]之前,这个实例的retainCount就是1了。在代码中不论是[NSArray array]或者[[NSArray alloc] init]都会增加此空数组实例的引用计数。
以下代码可以比较直观的体现这一点,与a无关的[NSArray array]语句增加了a的引用计数。
NSArray *a = [[NSArray alloc] init];[NSArray array];[NSArray array];NSLog('retainCount = %ld', a.retainCount);//输出结果为4
如果不开ARC的情况下,内存管理只要遵循Apple文档中的基本内存管理规则中的四条“黄金律”即可。
回答2:回答一下第一个问题输出时对象的内存已经被回收。向一个已经被回收的对象发送retainCount消息,输出结果应该是不确定的,如果该对象所占内存被复用了,有可能会造成程序异常崩溃。为什么这个不确定的值是1而不是0?因为最后一次执行release时,系统知道马上要回收内存,就没必要将retainCount减1了,因为不管减不减1,该对象肯定会被回收。不将这个值从1变成0,可以减少一次内存操作,加速对象的回收。结论:不要向已经释放的对象发送消息。