在通知中使用选择器的最佳实践是什么

Wil*_*jay 5 ios swift

在Swift 3中,要注册通知,我可以执行以下方法:

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")
}
Run Code Online (Sandbox Code Playgroud)

但是,在Xcode 9.0 beta 2(Swift 4.0)中,当我以这种方式注册通知时,对象方法应该具有前缀@objc,为什么呢?使用通知的最佳做法是什么?

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")
}
Run Code Online (Sandbox Code Playgroud)

Poc*_*chi 5

你没有错。

\n\n

事实上,苹果是这样解释你应该在 Swift 4 中使用选择器的:

\n\n
\n

在 Objective-C 中,选择器是一种引用 Objective-C 方法名称的类型。在 Swift 中,Objective-C 选择器由 Selector 结构表示,并且可以使用 #selector 表达式构造。要为可从 Objective-C 调用的方法创建选择器,请传递方法的名称,例如 #selector(MyViewController.tappedButton(sender:))。要为 property\xe2\x80\x99s Objective-C getter 或 setter 方法构造选择器,请传递以 getter: 或 setter: 标签为前缀的属性名称,例如 #selector(getter: MyViewController.myButton)。

\n
\n\n

文档链接在这里

\n\n

为了回答你的问题,为什么选择器实际上是在可可类之间发送消息的一种方式,而不是一个快速功能。所以它们实际上是基于 Objective-C 的,因此你需要保持它们之间的兼容性。

\n\n

选择器:

\n\n
\n

选择器是用于选择要为对象执行的方法的名称,或者是编译源代码时替换名称的唯一标识符。选择器本身不执行任何操作。它只是标识一个方法。使选择器方法名称与普通字符串不同的唯一原因是编译器确保选择器是唯一的。选择器的有用之处在于\n(与运行时结合)它的作用就像一个动态函数\n指针,对于给定的名称,自动指向\n适合于它的类的方法的实现\xe2\ x80\x99s 与\n 一起使用。

\n
\n\n

您可以在此处阅读有关选择器的更多信息。

\n\n

但基本上,它们只是可可使用的“消息传递”界面的一部分。

\n