簡體   English   中英

iOS無法刪除通知觀察者。 Deinit沒有被召喚

[英]iOS unable to remove Notification observer. Deinit not getting called

我有一個類似你可以在下面看到的UIView:

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....
    }
}

}

我遇到的問題是當用戶點擊后退按鈕並返回到另一個viewController時,我無法從這個特定的UIView中刪除觀察者。

ViewWillDisppear的調用,但deinit不叫。 奇怪的是,如果我們從viewDidLoad()刪除subscribeToNotifications() ,那么就會調用deinit

另一個問題與內存泄漏有關。 正如您在下面的屏幕截圖中看到的,當視圖訂閱通知並且用戶離開/重新進入視圖時,內存使用量會增加。 在此輸入圖像描述

現在將它與subscribeToNotifications()注釋掉的時間進行比較,內存使用量沒有增加,只有viewController的一個實例。 在此輸入圖像描述 結論是,在UIView的新實例的通知訂閱創建之間似乎存在相關性,因此沒有調用deinit

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

如果您需要更多信息,請與我們聯系。 :)

我發現removeObserver()只有在你使用這個版本的addObserver()時才有效

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

我猜測原始版本你並沒有真正指出觀察者是誰。

正如@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)

您應該將新添加的觀察者存儲在不透明對象( NSObjectProtocol )中,然后調用NotificationCenter.default.removeObserver(self.nameOfObserver)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM