问题描述
让我们考虑以下代码:
protocol A {
func doA()
}
extension A {
func registerForNotification() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardDidShow:"), name: UIKeyboardDidShowNotification, object: nil)
}
func keyboardDidShow(notification: NSNotification) {
}
}
现在看一下实现A的UIViewController子类:
Now look at a UIViewController subclass that implements A:
class AController: UIViewController, A {
override func viewDidLoad() {
super.viewDidLoad()
self.registerForNotification()
triggerKeyboard()
}
func triggerKeyboard() {
// Some code that make key board appear
}
func doA() {
}
}
但令人惊讶的是,这会因错误而崩溃:
But surprisingly this crashes with an error:
ke yboardDidShow:]:无法识别的选择器发送到实例
0x7fc97adc3c60
那么我应该在视图控制器本身中实现观察者吗?不能留在延期?
So should I implement the observer in the view controller itself? Can't it stay in the extension?
已经尝试过的事情。
制作一个类协议。
将keyboardDidShow添加到协议本身作为签名。
making A a class protocol.Adding keyboardDidShow to protocol itself as signature.
protocol A:class {
func doA()
func keyboardDidShow(notification: NSNotification)
}
推荐答案
我通过实现更新的 - addObserverForName:object:queue:usingBlock:
NSNotificationCenter的方法
并直接调用该方法。
I solved a similar problem by implementing the newer - addObserverForName:object:queue:usingBlock:
method of NSNotificationCenter
and calling the method directly.
extension A where Self: UIViewController {
func registerForNotification() {
NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: nil) { [unowned self] notification in
self.keyboardDidShow(notification)
}
}
func keyboardDidShow(notification: NSNotification) {
print("This will get called in protocol extension.")
}
}
这个例子将是l导致在协议扩展中调用 keyboardDidShow
。
This example will cause keyboardDidShow
to be called in the protocol extension.
这篇关于Swift使协议扩展成为通知观察者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!