Swift 3 ObjC在子类中未调用的可选协议方法 [英] Swift 3 ObjC Optional Protocol Method Not Called in Subclass

查看:335
本文介绍了Swift 3 ObjC在子类中未调用的可选协议方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类层次结构:

 类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:)


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


I have the following class hierarchy:

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

That implements one UITableViewDelegate protocol method, e.g. tableView:willDisplayCellAt:

In my class SpecificScrollableViewController, which inherits from ScrollableViewController, new optional protocol methods don't get called any more, e.g. tableView(_:heightForRowAt:)

解决方案

tl;dr you need to prefix the function declaration with its Objective-C declaration, e.g.

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

I was tipped off to this being a solution thanks to the Swift 3 Migration Guide which states:

If you implement an optional Objective-C protocol requirement in a subclass of a class that declares conformance, you’ll see a warning, "Instance method ‘…’ nearly matches optional requirement ‘…’ of protocol ‘…’"

• Workaround: Add an @objc(objectiveC:name:) attribute before the implementation of the optional requirement with the original Objective-C selector inside.

I'm fairly certain this is a bug: it appears that the the runtime dynamism that allows checking for selector capability does not get properly bridged in the Grand Swift Renaming when the protocol method is in the subclass. Prefixing the function declaration with the Objective-C name properly bridges the Swift to Objective-C and allows Swift 3 renamed methods to be queried with canPerformAction:withSender: from within Objective-C

这篇关于Swift 3 ObjC在子类中未调用的可选协议方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆