三個關於objective-c記憶體管理的疑惑,希望有人幫我解答
PHPz
PHPz 2017-04-24 09:12:06
0
2
367

疑惑:
1、內存管理:dealloc之後還能打印出retainCount = 1
main方法中:

person方法中覆寫的dealloc方法和打印結果

2、 兩個 category都只覆寫了dealloc方法,用來輸出驗證
Copy創建的物件release之後調用dealloc方法,但是在自動釋放池釋放物件時,又釋放了一次
為什麼會釋放兩次啊?

3、使用類別名稱方法建立對象,引用計數為2

PHPz
PHPz

学习是最好的投资!

全部回覆(2)
阿神
  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文件中的基本記憶體管理規則中的四條「黃金律」即可。

Ty80

回答第一個問題
輸出時物件的記憶體已經被回收。
向一個已經被回收的物件發送retainCount訊息,輸出結果應該是不確定的,如果該物件所佔記憶體被重複使用了,有可能會造成程式異常崩潰。
為什麼這個不確定的值是1而不是0?因為最後一次執行release時,系統知道馬上要回收內存,就沒必要將release时,系统知道马上要回收内存,就没必要将retainCount減1了,因為不管減不減1,該物件肯定會被回收。
不將這個值從1變成0,可以減少一次記憶體操作,加速物件的回收。
結論:不要向已經釋放的物件發送訊息。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板