6

In Swift 3, to register a notification, I can do the following ways:

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.n1(notification:)), name: Notification.Name("123"), object: nil)
func n1(notification: Notification){
    print("123")
}


// #selector is more brief
NotificationCenter.default.addObserver(self, selector: #selector(n2), name: Notification.Name("456"), object: nil)
func n2(notification: Notification){
    print("456")
}

However, in Xcode 9.0 beta 2 (Swift 4.0), when I register a notification this way, the object method should have a prefix @objc, why? What is the best practice to use Notification?

Argument of '#selector' refers to instance method 'n1(notification:)' that is not exposed to Objective-C

//Add '@objc' to expose this instance method to Objective-C
@objc func n1(notification: Notification){
    print("123")
}

@objc func n2(notification: Notification){
    print("456")
}
Willjay
  • 6,381
  • 4
  • 33
  • 58

1 Answers1

5

You are not wrong.

As a matter of fact this is how apple explains you should be using selectors in Swift 4:

In Objective-C, a selector is a type that refers to the name of an Objective-C method. In Swift, Objective-C selectors are represented by the Selector structure, and can be constructed using the #selector expression. To create a selector for a method that can be called from Objective-C, pass the name of the method, such as #selector(MyViewController.tappedButton(sender:)). To construct a selector for a property’s Objective-C getter or setter method, pass the property name prefixed by the getter: or setter: label, such as #selector(getter: MyViewController.myButton).

Documentation link here.

And to answer your question about why, well selectors are actually a way to send messages between cocoa classes, not a swift feature. So they are actually based on Objective-C thus why you need to keep compatibility between them.

Selectors:

A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn’t do anything. It simply identifies a method. The only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique. What makes a selector useful is that (in conjunction with the runtime) it acts like a dynamic function pointer that, for a given name, automatically points to the implementation of a method appropriate for whichever class it’s used with.

You can read more about selectors here.

But basically, they are just part of the "messaging" interface used by cocoa.

Pochi
  • 13,391
  • 3
  • 64
  • 104