繁体   English   中英

Swift 3 ObjC在子类中不调用的可选协议方法

[英]Swift 3 ObjC Optional Protocol Method Not Called in Subclass

我有以下类层次结构:

class ScrollableViewController: UIViewController, UITableViewDelegate { // ... }

这实现了一个UITableViewDelegate协议方法,例如tableView:willDisplayCellAt:

在我的类SpecificScrollableViewController ,它继承自ScrollableViewController ,新的可选协议方法不再被调用,例如tableView(_:heightForRowAt:)

tl; dr你需要在函数声明前面加上Objective-C声明,例如

@objc(tableView:heightForRowAtIndexPath:)
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  // return stuff
}

由于Swift 3迁移指南指出,我被告知这是一个解决方案:

如果在声明一致性的类的子类中实现可选的Objective-C协议要求,您将看到一个警告,“实例方法'......几乎匹配协议''''的可选要求'...'”

•解决方法:在实现可选需求之前添加@objc(objectiveC:name:)属性,其中包含原始Objective-C选择器。

我很确定这是一个错误:当协议方法在子类中时,似乎允许检查选择器功能的运行时动态在Grand Swift重命名中没有得到正确的桥接。 使用Objective-C名称前缀函数声明正确地将Swift桥接到Objective-C,并允许使用canPerformAction:withSender:查询Swift 3重命名的方法canPerformAction:withSender:来自Objective-C

对于普通子类,这似乎在Swift 3.0.1中得到修复,但对于通用子类不固定:

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM