Swi*_*ter 24 ios swift swift2 protocol-extension
我们考虑以下代码:
protocol A {
func doA()
}
extension A {
func registerForNotification() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardDidShow:"), name: UIKeyboardDidShowNotification, object: nil)
}
func keyboardDidShow(notification: NSNotification) {
}
}
Run Code Online (Sandbox Code Playgroud)
现在看一下实现A的UIViewController子类:
class AController: UIViewController, A {
override func viewDidLoad() {
super.viewDidLoad()
self.registerForNotification()
triggerKeyboard()
}
func triggerKeyboard() {
// Some code that make key board appear
}
func doA() {
}
}
Run Code Online (Sandbox Code Playgroud)
但令人惊讶的是,这会因错误而崩溃:
keyboardDidShow:]:无法识别的选择器发送到实例0x7fc97adc3c60
那么我应该在视图控制器本身中实现观察者吗?不能留在延期?
以下事情已经尝试过.
制作A类协议.将keyboardDidShow添加到协议本身作为签名.
protocol A:class {
func doA()
func keyboardDidShow(notification: NSNotification)
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*nio 34
我通过实现更新的- addObserverForName:object:queue:usingBlock:
方法NSNotificationCenter
并直接调用该方法解决了类似的问题.
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.")
}
}
Run Code Online (Sandbox Code Playgroud)
此示例将导致keyboardDidShow
在协议扩展中调用.
小智 1
为了避免崩溃,请在使用该协议的 Swift 类中实现观察者方法。
\n\n实现必须在 Swift 类本身中,而不仅仅是协议扩展中,因为选择器始终引用 Objective-C 方法,而协议扩展中的函数不能用作 Objective-C 选择器。然而,如果 Swift 类继承自 Objective-C 类,则 Swift 类中的方法可用作 Objective-C 选择器
\n\n\xe2\x80\x9c如果您的 Swift 类继承自 Objective-C 类,则该类中的所有方法和属性都可用作 Objective-C 选择器。\xe2\x80\x9d
\n\n另外,在 Xcode 7.1 中,在调用中将其指定为观察者时self
必须向下转换。AnyObject
addObserver
protocol A {\n func doA()\n}\n\nextension A {\n func registerForNotification() {\n NSNotificationCenter.defaultCenter().addObserver(self as! AnyObject,\n selector: Selector("keyboardDidShow:"),\n name: UIKeyboardDidShowNotification,\n object: nil)\n }\n\n func keyboardDidShow(notification: NSNotification) {\n print("will not appear")\n }\n}\n\nclass ViewController: UIViewController, A {\n override func viewDidLoad() {\n super.viewDidLoad()\n self.registerForNotification()\n triggerKeyboard()\n }\n\n func triggerKeyboard(){\n // Some code that makes the keyboard appear\n }\n\n func doA(){\n }\n\n func keyboardDidShow(notification: NSNotification) {\n print("got the notification in the class")\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
6751 次 |
最近记录: |