三个关于objective-c内存管理的疑惑,希望能有人帮我解答


疑惑:
1、内存管理:dealloc之后还能打印出retainCount = 1
main方法中:
clipboard.png
person方法中覆写的dealloc方法和打印结果
clipboard.png

2、 两个 category都只覆写了dealloc方法,用来输出验证
Copy创建的对象release之后调用dealloc方法,但是在自动释放池释放对象时,又释放了一次
为什么会释放两次啊?
clipboard.png

3、使用类名方法创建对象,引用计数为2
clipboard.png

内存管理 objective-c

小小miku 9 years, 8 months ago

回答一下第一个问题
输出时对象的内存已经被回收。
向一个已经被回收的对象发送 retainCount 消息,输出结果应该是不确定的,如果该对象所占内存被复用了,有可能会造成程序异常崩溃。
为什么这个不确定的值是1而不是0?因为最后一次执行 release 时,系统知道马上要回收内存,就没必要将 retainCount 减1了,因为不管减不减1,该对象肯定会被回收。
不将这个值从1变成0,可以减少一次内存操作,加速对象的回收。
结论:不要向已经释放的对象发送消息。

邻人四十二 answered 9 years, 8 months ago

  1. 非一般的瓜子的答案是对的。

  2. NSMutableArray 对象调用 copy 返回的是一个NSArray对象,所以在 [array4 release] 被调用时array4的dealloc方法被调用,输出 NSArray dealloc
    随后autoreleasepool被销毁,array3被释放,array3的dealloc方法被调用,因为NSMutableArray的dealloc方法中调用了 [super dealloc] ,所以输出了随后的两句。

  3. 根据 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文档中的基本内存管理规则 中的四条“黄金律”即可。

ljj3388 answered 9 years, 8 months ago

Your Answer