如果我們繼承UIView
,在任何的這個新類的實例方法,做在iOS上,在UIView的實例方法中,如果我們做[self removeFromSuperview],爲什麼自我繼續存在?
[self removeFromSuperview];
[foo someMessage];
_a = _a + 1;
self.b++;
for (int i = 0; i < 100000000; i++) {
self.b++;
//NSLog(@"b is %i", self.b);
}
會發生什麼?假設超級視圖是唯一聲稱擁有此視圖的所有者,那麼將立即釋放self
?
第一行是發送一個局部變量foo
引用外部對象的消息someMessage
。第二行是一個局部變量_b
。第三行是屬性b
。接下來的幾行只是延遲一些。
嘗試使用Xcode 4.5和iPhone 5(iOS 6)時,代碼實際上運行時不會崩潰。代碼在-touchesBegan
內完成。只有在大延遲循環完成後,視圖纔會在屏幕上消失,可能是因爲主循環現在調用drawRect
代替rootViewController.view
,並且顯示視圖已經消失(視圖在延遲循環之前從視圖層次中消失了,但沒有反映在屏幕上)。
如果我只將循環計數到1000或10000,並在該循環內使用NSLog
,則該數字實際上可以很好地打印出來而不會發生任何崩潰。 更新:據說該對象可能仍然可以訪問一段時間,但似乎即使是30秒或一分鐘,代碼仍然運行沒有任何問題。
那麼這是如何工作的?如果使用儀器,我實際上只能看到這個FooView
對象在大延遲循環後才離開「分配」表。所以奇怪的是,似乎FooView
對象直到後來才被釋放,而不是在removeFromSuperView
的位置。
我也有一個[self.presentingViewController dismissViewControllerAnimated ...]
即駁回self
,然後下一行,self.presentingViewController
再次使用,self.presentingViewController
成爲nil
,但如果我還添加了一個循環遞增整數屬性爲10000和使用NSLog
打印出來,它打印出來也很好。
如果你有一個懸掛指針,訪問它仍然會崩潰,即使內存還沒有被重用。 –
@Carl:_發送message_不會。 'NSNumber * n = [[NSNumber alloc] initWithInteger:10]; [n版本]; NSLog(@「%f」,[n floatValue]);' –
哇。 「NSNumber」就是一個很好的例子,因爲它有各種優化,但是一個簡單的NSObject子類仍然會在釋放後立即對消息作出響應,並且至少在改變堆的其他操作之前不會崩潰,但是不會100%機會。現在我想到它確實很有意義。感謝您的啓發! –