声明 NotificationCenter.default.addObserver [swift]
Posted
技术标签:
【中文标题】声明 NotificationCenter.default.addObserver [swift]【英文标题】:declare NotificationCenter.default.addObserver [swift] 【发布时间】:2020-02-25 15:53:27 【问题描述】:如何在 Swift 中将观察者添加到通知中心?
这样做:
override func viewDidLoad()
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ReloadData), name: NSNotification.Name(rawValue: "ReloadData"), object: nil)
@objc func ReloadData(notification: NSNotification)
// func
print ("FUNC TEST")
但是每次控制器关闭/打开(在标签栏的标签之间切换)时,都会添加一个新的侦听器。 当我打电话时
print ("Call Notif")
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadData"), object: nil)
"func ReloadData" 被多次调用。控制台:
Call Notif
FUNC TEST
FUNC TEST
将再次在标签栏的标签之间切换。
Call Notif
FUNC TEST
FUNC TEST
FUNC TEST
我怎么能只答应你一次?
【问题讨论】:
通过NotificationCenter.default.removeObserver(self)
取消订阅viewWillDisappear
方法并订阅viewWillAppear
。 This is actually a duplicate question
这能回答你的问题吗? Swift NotificationCenter remove observer quickest way
阿列克谢,是的!但我需要观察者留下来。我不希望它被删除。我想要一份。
虽然上面的评论解决了您的问题的可见部分,但真正的问题是 您在内存中加载了该控制器的多个实例。所以你应该明白为什么会发生这种情况。这肯定是内存泄漏/糟糕的设计。
你订阅了你的 viewControllers 超类中的通知吗?因为 UITableViewController 的控制器只创建一次(viewDidLoad 在创建时被调用一次)并且在它们的父级(tabbarcontroller)被释放时被释放。
【参考方案1】:
我的情况和你类似。阅读 https://***.com/a/60399071/14414215 和 https://***.com/a/51745479/1040347 并尝试后,在我使用 UITabBarController 设计将数据传递到不同选项卡的特定场景中,它对我不起作用。
Tab1 是主屏幕 Tab2 是锻炼库(用户选择数据)
然后使用 TabBarController 作为中间 https://***.com/a/65499693/14414215 将数据从 Tab2 传递到 Tab1。在 Tab1 中添加 removeObserver 时
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
这将导致数据无法从 Tab2 传递到 Tab1,因为每当用户从 Tab1 移动到 Tab2 时都会取消订阅通知。
我也尝试将 removeObserver 添加到 TabBarController 中,但这没有做任何事情。
最后,起作用的是从 objc 中取消订阅,例如:
在 Tab1 中:
override func viewDidLoad()
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ReloadData), name: NSNotification.Name(rawValue: "ReloadData"), object: nil)
@objc func ReloadData(notification: NSNotification)
// func
print ("FUNC TEST")
NotificationCenter.default.removeObserver(self). // Adding it here works and its then only called ONCE
【讨论】:
【参考方案2】:不管你喜不喜欢,最简单的解决方案就是利用控制器的生命周期。
-
订阅控制器每次出现或加载的通知。
删除每次deinit
或控制器消失的通知。
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadData"), object: nil)
override func viewWillDisappear(_ animated: Bool)
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
如果您的每个控制器都有一个基类,您可以将removeObserver()
放在该基类中。
【讨论】:
以上是关于声明 NotificationCenter.default.addObserver [swift]的主要内容,如果未能解决你的问题,请参考以下文章