Swift 3 ObjC可选协议方法不在子类中调用
我有以下类层次结构:
class ScrollableViewController: UIViewController, UITableViewDelegate { // ... }
这实现了一个UITableViewDelegate
协议方法,例如tableView:willDisplayCellAt:
在我的类SpecificScrollableViewController
,inheritance自ScrollableViewController
,新的可选协议方法不会再被调用,例如tableView(_:heightForRowAt:)
你需要在函数声明前加上Objective-C声明,例如:
@objc(tableView:heightForRowAtIndexPath:) func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { // return stuff }
我被告知这是一个解决scheme,感谢“ Swift 3移植指南” ,其中指出:
如果您在声明一致性的类的子类中实现可选的Objective-C协议要求,则会看到一个警告,“实例方法…”几乎与协议“…”的可选要求“…”
•解决方法:在使用原始Objective-Cselect器实现可选需求之前,添加
@objc(objectiveC:name:)
属性。
我相当肯定这是一个错误:当协议方法在子类中时,似乎允许检查select器能力的运行时dynamic并没有在Grand Swift Renaming中正确桥接。 使用Objective-C名称前缀函数声明将Swift桥接到Objective-C,并允许使用canPerformAction:withSender:
来查询Swift 3重命名的方法canPerformAction:withSender:
from Objective-C
这似乎在Swift 3.0.1中正常的子类固定,但不是固定的generics子类:
class A: NSObject, UITableViewDelegate {} class B: A { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {} } class C<T>: A { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {} } print(#selector(B.tableView(_:didSelectRowAt:))) // tableView:didSelectRowAtIndexPath: print(#selector(C<Int>.tableView(_:didSelectRowAt:))) // tableView:didSelectRowAt:
请参阅: https : //bugs.swift.org/browse/SR-2817
修复它: https : //stackoverflow.com/a/39416386/1109892
@objc(tableView:heightForRowAtIndexPath:) func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { // return stuff }