8

我有一个类似于您在下面看到的 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未被调用。奇怪的是,如果我们从中删除subscribeToNotifications()viewDidLoad()就会deinit调用。

另一个问题与内存泄漏有关。正如您在下面的屏幕截图中看到的,当视图确实订阅了通知并且用户离开/重新进入视图时,内存使用量会增加。在此处输入图像描述

现在将其与subscribeToNotifications()注释掉时进行比较,内存使用量没有增加,并且只有一个 viewController 实例。 在此处输入图像描述 结论是,通知订阅创建 UIView 的新实例之间似乎存在相关性,因此deinit没有被调用。

我想知道是否有一种方法可以取消初始化视图并取消订阅通知。

如果您需要更多信息,请告诉我。:)

4

3 回答 3

5

我发现 removeObserver() 仅在您使用此版本的 addObserver() 时才有效

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

我猜你的原始版本实际上并没有表明观察者是谁。

于 2017-05-12T12:49:58.907 回答
2

正如@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)
于 2017-05-12T13:58:57.897 回答
0

您应该将新添加的观察者存储在不透明对象 ( NSObjectProtocol) 中,然后调用NotificationCenter.default.removeObserver(self.nameOfObserver)

于 2019-05-07T12:48:47.437 回答