2009-08-21 35 views
5

在我關於使用委託或UIControl事件的問題,這是在肯德爾黑爾姆施泰特Geln的回答是:iPhone dev - 代表,通知,退訂前取消訂閱?

兩者都是關於一個相等的負載一起工作 - 一個代表,你必須設定自己,然後記得在您釋放之前取消自己的設置。你必須對通知做同樣的事情,記得在你被釋放之前開始傾聽並取消訂閱。

這是什麼意思,退訂前取消訂閱,取消自定義?我沒有做過任何事情。有人可以解釋它是什麼以及如何去做?

謝謝!

回答

8

如果您的生命週期比您委派的對象短,您需要將自己作爲委託移除。在幾乎所有情況下,您的壽命等於或長於您所委派的對象。這就是說,這是一個很好的習慣。考慮一下你是UITableView的委託的情況。在-init,也許你撥打:

self.myTableView.delegate = self; 

那麼它可能會是明智-dealloc

_myTableView.delegate = nil; 
[_myTableView release]; 
_myTableView = nil; 

之所以這樣做是myTableView可能被其他對象所保留,所以可能無法解除分配當你釋放它。如果在您離開後進行委託調用,您的應用程序將崩潰。所以清除委託指針是一個好主意。

同樣,對於NSNotificationCenter,你應該這樣刪除自己在-dealloc

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

這將刪除你的所有觀察。你應該在-dealloc中這樣做,如果你的課程註冊了任何通知。如果您不這樣做,並且在您離開後發現您正在觀察的通知,則該應用程序將崩潰。

這對於NSTimers不是必需的,因爲NSTimers保留其目標(您)。

+1

謝謝!那麼UIControl事件呢?我應該怎麼做[myButton removeTarget:....]? – mk12 2009-08-21 15:22:06

+0

這是否也適用於DataSources? – mk12 2009-08-21 15:22:55

+0

對於UIControl,這是一個有趣的問題。我不確定是否addTarget:...保留。如果沒有,那麼你是對的,你應該刪除自己。數據源與代表相同。 – 2009-08-21 18:58:35

1

我相信你只需將代表設置爲零即可。

myOjectOrClass.delegate = nil; 
+0

因此,您必須爲您分配的每個代表執行此操作。如果你不這樣怎麼辦?事件怎麼樣([control addTarget:self action:....]? – mk12 2009-08-21 03:24:53

+0

我的書和示例代碼中,我從來沒有見過這樣的內容? – mk12 2009-08-21 03:25:51

+0

我們來到相同的 - 在調用發佈之前將委託設置爲零。 – 2012-08-02 13:35:19

1

傳遞給UIControl addTarget方法時,不會對目標執行保留。儘管文檔沒有具體提及這一點,但我已經寫了一個簡單的測試來證明這個事實。

如果您添加一個目標作爲控件事件的觀察者,然後釋放它,您將注意到保留計數下降(可能導致它被回收)。

這意味着控件永遠不會阻止目標被釋放