Search code examples
swiftswift2nsnotificationcenter

Where is the right place to remove notification observers in Swift 2?


I have this code, taken from this answer: https://stackoverflow.com/a/29099066/406322

extension NSNotificationCenter {
    func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
        NSNotificationCenter.defaultCenter().removeObserver(observer, name: name, object: object)
        NSNotificationCenter.defaultCenter().addObserver(observer, selector: selector, name: name, object: object)
    }
}

Now, in my view controller, I am setting my observers in viewDidLoad():

override func viewDidLoad() {
        super.viewDidLoad()
        setObservers()
}

func setObservers() {
        NSNotificationCenter.defaultCenter().setObserver(self, selector: #selector(BaseController.handleComment(_:)), name: "newComment", object: nil)
}

However, even with using this extension, where the observer is removed before getting added, each time I exit the view controller, and return to it, I get multiple notifications (one extra each time).

How is this possible?


Solution

  • If you need this setObserver extension, you are very likely doing something wrong. You should be able to balance your registration and removal easily. If you can't, your notification management is very likely too complicated or in the wrong place.

    Typically the correct place to add observations is in viewWillAppear (or viewDidAppear, either is fine), and remove them in viewDidDisappear (or viewWillDisappear). This ensures that you do not receive notifications while you are offscreen, even if the view controller still exists (which is common).

    If your view controller requires that it receive notifications while it is offscreen, then you have a design problem. View controllers should only manage onscreen views. If they're doing anything else, you have put too much of the model into the controller.

    As @rmaddy notes, your specific problem is likely that you have two instances of this view controller. That's may be fine or it might be a mistake (it depends on how the view controller works). But if you balance adding and removing your registration when going on and offscreen, that part will be fine.