Swift 3 ObjC Optional Protocol Method Not Called in Subclass

后端 未结 2 1766
猫巷女王i
猫巷女王i 2020-12-05 03:35

I have the following class hierarchy:

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

That implements one

2条回答
  •  北海茫月
    2020-12-05 04:09

    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

提交回复
热议问题