Practicing writing a project using MVP. There is a task - to update the table after the new element has been added to the model.

Method inside DataStorageObserver that updates the model:

func addContact(contact: Contact) { DataStorage.sharedInstance.contactList.append(contact) NSNotificationCenter.defaultCenter().postNotificationName(Constants.Identifiers.sharedInstance.contactListUpdateIdentifier, object: nil) } 

View implements protocol methods

 protocol ContactListViewProtocol: class { func updateData() } 

The update method itself, which is inside the View (the role of which is played by the UITableViewController)

 func updateData() { self.tableView.reloadData() } 

Inside the presenter there is a method:

 required init(view: ContactListViewProtocol) { self.view = view NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ContactListViewProtocol.updateData), name: Constants.Identifiers.sharedInstance.contactListUpdateIdentifier, object: nil) } 

Xcode suggests that the last required init contains an error

Argument of '#selector' refers to a method that is not subject to Objective-C

If you take a hint from Xcode, then it offers to substitute the @objc label to the method in the ContactListPresenterProtocol, which (method) does not relate to the update logic (I suppose that it is ide). How best to implement the update? Where should @objc be put down? Is it worth it?

    2 answers 2

    The error with you is that you call updateData on self, and the method in your view class

     NSNotificationCenter.defaultCenter().addObserver(self.view,selector: #selector(ContactListViewProtocol.updateData), name: Constants.Identifiers.sharedInstance.contactListUpdateIdentifier, object: nil) 
    • Thank you, that is, I can hang the observers on any views from their receivers, and I hung the observer on the presenter who was pulling the method from the view (for which I accept "uiviewcontroller"). But there is one nuance, how can I implement mvp, in which the model tells the presenter that it needs to be updated, and the presenter pulls the view method, if I hang the selector on the view and throw the notification from the model (it turns out that I update the view with the model)? - user204104

    Selectors are part of ObzhS and can only be used with methods that exist in Obj-C runtime. You cannot call the swift method with a selector.

    If your class is inherited from NSObject, then all its public methods are visible automatically. Since your class is not inherited from NSObject, you need to use the @objc attribute to indicate that you want this method to be available for calling using selector.

    #selector() is a new syntax available in Swift 2.2. He calls the compiler to check that the selector you want to call exists. Old syntax will be removed in Swift 3.0

    • Thanks for the answer, but here's the problem: when I call from the class presenter, which inherits from NSObject, by the selector, the viewController method (UIViewController is inherited somewhere at the top of the hierarchy from NSObject), the link to the viewController is contained within the presenter-class then I get the error 1) unrecognized selector sent to instance, as well as the terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '- [MVPtest.ContactListPresenter updateData:]: unrecognized selector sent to instance 0x7fd2f8d00660' [link] ( github. com / dotprox / iOS_MVP ) - user204104
    • @DotProx there is no .proj file - Max Mikheyenko
    • it is missing its project.pbxproj file. - Max Mikheyenko
    • dropbox.com/sh/rktondkiiwphu10/AAAflFpGNo1xxzB9bDlOJSoga?dl=0 I do not understand why, git swears on xproj - user204104