2017-05-12 52 views
8

我有一個類似於下面你可以看到一個UIView:iOS無法刪除通知觀察者。 DEINIT沒有得到所謂的

class ViewTaskViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
override func viewDidLoad() { 
    super.viewDidLoad() 
    subscribeToNotifications() 
} 

func subscribeToNotifications() { 
    let notification = NotificationCenter.default 
    notification.addObserver(forName: Notification.Name(rawValue: "TimerUpdated"), object: nil, queue: nil, using: handleUpdateTimer) 
    print("Subscribed to NotificationCenter in ViewTaskViewController") 
} 

override func viewWillDisappear(_ animated: Bool) { 
    super.viewWillDisappear(animated) 
    print("TUFU TUFU TUFU") 
    NotificationCenter.default.removeObserver(self) 
} 

deinit { 
    print("DENINT") 
} 

@objc func handleUpdateTimer(notification: Notification) { 
    if let userInfo = notification.userInfo, let timeInSeconds = userInfo["timeInSeconds"] as? Int { 

     withUnsafePointer(to: &self.view) { 
      print("We got timeeeeee \(timeInSeconds) \($0)") 
     } 

     //do something here.... 
    } 
} 

}

我遇到的問題是,我無法從在這個特殊的UIView刪除觀察員用戶點擊後退按鈕並返回到另一個viewController。

ViewWillDisppear被調用,但不調用deinit。奇怪的是,如果我們從viewDidLoad()中刪除subscribeToNotifications(),則調用deinit

另一個問題與內存泄漏有關。正如您在下面的屏幕截圖中看到的那樣,當視圖預訂通知並且用戶離開/重新進入視圖時,內存使用率會增加。 enter image description here

現在比較一下,當subscribeToNotifications()被註釋掉時,沒有增加內存使用量並且只有viewController的一個實例。 enter image description here 結論是,通知訂閱創建UIView的新實例似乎存在相關性,因此deinit未被調用。

我想知道是否有辦法可以取消初始化視圖並取消訂閱通知。

如果您需要更多信息,請讓我知道。 :)

+0

您正在使用的'addObserver'方法的文檔說:「要取消註冊觀察,請將此方法返回的**對象傳遞給removeObserver(_ :)。」相反,你似乎認爲'self'是註冊的對象。 –

回答

4

我發現removeObserver()只有當你使用這個版本的addObserver()的作品

notification.addObserver(self, selector:#selector(self.handleUpdateTimer), name: Notification.Name(rawValue: "TimerUpdated"), object: nil) 

我跟你實際上並沒有說明原來的版本誰觀察者猜測。

+0

非常感謝你!我已經嘗試了哈立德的建議,但仍然沒有得到它的觀察員。但是你的方法肯定有助於解決問題! :) –

1

正如@Spads說,你可以使用

NotificationCenter.default.addObserver(self, selector: #selector(subscribeToNotifications), name: NSNotification.Name(rawValue: "TimerUpdate"), object: nil) 

,或者你已經有了一個。 你可以通過它的名字刪除您的通知,或者是參考

NotificationCenter.default.removeObserver(self, name: "TimerUpdate", object: nil) 

,如果你宣佈你在你的類的頂部通知,那麼你可以直接通過你的情況要刪除您的通知的參考通知

NotificationCenter.default.removeObserver(notification) 
+0

所以我甚至在提交這個問題之前嘗試過,並沒有得到它的工作,儘管另一種添加觀察者的方法似乎已經做到了! :) 謝謝 –