从 NSNotification 事件调用协议方法的默认实现
Call default implementation of protocol method from NSNotification event
我有一个供 UIViewController
s 使用的协议,它有两个默认的方法实现
protocol RotationMonitor {
func registerForRotationNotifications()
func viewDidRotate()
}
extension RotationMonitor where Self: UIViewController {
func registerForRotationNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "viewDidRotate", name: UIDeviceOrientationDidChangeNotification, object: nil)
}
func viewDidRotate() {
switch UIDevice.currentDevice().orientation {
case .LandscapeLeft, .LandscapeRight:
print("Device is landscape")
case .Portrait:
print("Device is portrait")
case .PortraitUpsideDown:
print("Device is portrait, upside down.")
default:
// ignore
break;
}
}
}
直接在视图控制器的代码中调用这些方法对这两种方法都适用;调用 registerForRotationNotifications()
为设备旋转通知注册视图控制器,调用 viewDidRotate()
正确执行 switch 语句。但是,在调用 registerForRotationNotifications()
并收到实际通知后,我遇到了消息
崩溃
2015-11-03 10:46:53.111 APP_NAME[57415:2484548] -[APP_NAME.ViewController viewDidRotate]: unrecognized selector sent to instance 0x7f8afb019a00
我认为这可能是因为视图控制器没有提供 public 对 viewDidRotate()
方法的访问,但我无法在任何对象上使用 public
关键字协议方法定义或默认实现。
有没有办法让通知中心正确调用协议扩展中的默认实现?我不想使用像从视图控制器本身调用 viewDidRotate()
方法这样的解决方法,我希望能够让视图控制器简单地注册通知并将工作卸载到协议上扩展。
你不能按照你想要的方式来做这件事。请记住,Objective-C 只知道 Objective-C 语言功能。它对 Swift 枚举、结构、泛型、元组等一无所知;这样的 Swift 特征对 Objective-C 是完全不可见的。同样,Objective-C 对 Swift 协议一无所知,尤其是对 Swift 协议扩展一无所知。就 Objective-C 而言,viewDidRotate
方法不存在于视图控制器 class 中。因此崩溃。
我有一个供 UIViewController
s 使用的协议,它有两个默认的方法实现
protocol RotationMonitor {
func registerForRotationNotifications()
func viewDidRotate()
}
extension RotationMonitor where Self: UIViewController {
func registerForRotationNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "viewDidRotate", name: UIDeviceOrientationDidChangeNotification, object: nil)
}
func viewDidRotate() {
switch UIDevice.currentDevice().orientation {
case .LandscapeLeft, .LandscapeRight:
print("Device is landscape")
case .Portrait:
print("Device is portrait")
case .PortraitUpsideDown:
print("Device is portrait, upside down.")
default:
// ignore
break;
}
}
}
直接在视图控制器的代码中调用这些方法对这两种方法都适用;调用 registerForRotationNotifications()
为设备旋转通知注册视图控制器,调用 viewDidRotate()
正确执行 switch 语句。但是,在调用 registerForRotationNotifications()
并收到实际通知后,我遇到了消息
2015-11-03 10:46:53.111 APP_NAME[57415:2484548] -[APP_NAME.ViewController viewDidRotate]: unrecognized selector sent to instance 0x7f8afb019a00
我认为这可能是因为视图控制器没有提供 public 对 viewDidRotate()
方法的访问,但我无法在任何对象上使用 public
关键字协议方法定义或默认实现。
有没有办法让通知中心正确调用协议扩展中的默认实现?我不想使用像从视图控制器本身调用 viewDidRotate()
方法这样的解决方法,我希望能够让视图控制器简单地注册通知并将工作卸载到协议上扩展。
你不能按照你想要的方式来做这件事。请记住,Objective-C 只知道 Objective-C 语言功能。它对 Swift 枚举、结构、泛型、元组等一无所知;这样的 Swift 特征对 Objective-C 是完全不可见的。同样,Objective-C 对 Swift 协议一无所知,尤其是对 Swift 协议扩展一无所知。就 Objective-C 而言,viewDidRotate
方法不存在于视图控制器 class 中。因此崩溃。