2017-05-12 47 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

所以我甚至在提交这个问题之前尝试过,并没有得到它的工作,尽管另一种添加观察者的方法似乎已经做到了! :) 谢谢 –