NotificationCenter 动作堆叠在彼此之上?

NotificationCenter actions stacking ontop of eachother?

我有代表来自 Firebase 的用户帖子的按钮。

当视图出现时,我正在重新绘制圆圈以使其与信息保持同步。但是,每次我重新绘制圆圈时,它都会通过在调用操作的次数上加 1 来弄乱我与按钮关联的操作。

我有一个 class 负责将操作添加到按钮上。

 override init(frame: CGRect) {
        super.init(frame: frame)
 let doubleTap = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapAction(sender:)))
self.addGestureRecognizer(doubleTap)

}
func doubleTapAction(sender : UIButton) {
        print("Double tapped")
        NotificationCenter.default.post(name: .didDoubleTap , object: nil, userInfo: ["tagTapped" : self.tag])
    }

所以代码都是在我的 "buttonPost" class.

中完成的

然后在我的 mainVC 上,我在 viewDidLoad

中为 .didDoubleTap 添加了 NotificationCenter 的观察者
 NotificationCenter.default.addObserver(self, selector: #selector(self.didDoubleTapOnACircle(sender:)), name: .didDoubleTap , object: nil)

最后我有了处理我想要它做的事情的功能:

 func didDoubleTapOnACircle(sender: Notification) {
        print("double tapped action called")
 }

发生的事情是,当我第一次加载页面按钮时,页面按钮被绘制并正常工作。如果我双击一个圆圈,我会从我的 class 函数中获得 "Double tapped" 并从我的观察者函数中获得 "double tapped action called"。

问题是当我离开负责绘制圆圈的 viewcontroller 然后我回到它时 "didDoubleTapOnCircle" 被调用了两次,"double tapped action called" 被打印了两次,但是 "double tapped" 被打印了一次。如果我离开并返回主页(也就是重画圆圈 10 次),"double tapped action called" 将被打印 10 次,而 "Double tapped" 仍将被调用一次。

这是什么原因造成的?

所以 tl;dr 是我将来自 firebase 的用户帖子表示为可以在首页上双击的按钮。当我最初加载按钮时效果很好,doubletapp 操作被调用一次。每次离开和返回按钮页面时,调用 didDoubleTapOnCircle 函数的次数都会增加 1。

我需要删除通知的观察者。我假设因为我完全重绘了按钮,所以这不是必需的,但删除观察者解决了这个问题。

Apple 建议在 viewWillAppear / Dissapear 中处理观察者侦听器。

 override func viewWillAppear(_ animated: Bool) {
        NotificationCenter.default.addObserver(self, selector: #selector(self.handleTapped(sender:)), name: .didTap , object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.didDoubleTapOnACircle(sender:)), name: .didDoubleTap , object: nil)
    }

    override func viewWillDisappear(_ animated: Bool) {


        NotificationCenter.default.removeObserver(self, name: .didTap, object: nil)
        NotificationCenter.default.removeObserver(self, name: .didDoubleTap, object: nil)
        NotificationCenter.default.removeObserver(self)


}