Swift @objc协议 - 区分具有类似签名的可选方法

时间:2015-12-04 10:46:24

标签: swift optional swift-protocols

假设我们在Swift中有一个协议:

@objc protocol FancyViewDelegate {
  optional func fancyView(view: FancyView, didSelectSegmentAtIndex index: Int)
  optional func fancyView(view: FancyView, shouldHighlightSegmentAtIndex index: Int) -> Bool
}

请注意,这两种方法都是可选的,并且具有相同的前缀签名。

现在我们的FancyView课程如下:

class FancyView: UIView {
  var delegate: FancyViewDelegate?

  private func somethingHappened() {
    guard let delegateImpl = delegate?.fancyView else {
      return
    }

    let idx = doALotOfWorkToFindTheIndex()

    delegateImpl(self, idx)
  }
}

编译器跳出我们的脸:

enter image description here

我们可以将somethingHappened()更改为:

private func somethingHappened() {
  let idx = doALotOfWorkToFindTheIndex()

  delegate?.fancyView?(self, didSelectSegmentAtIndex: idx)
}

但是,正如您所看到的那样,我们冒着做很多工作的风险只是为了丢弃索引,因为委托没有实现可选方法。

问题是:我们如何if letguard let使用类似的前缀签名绑定两个可选方法的实现。

1 个答案:

答案 0 :(得分:0)

首先,您的目标C协议需要向NSObjectProtocol确认,以确保我们可以内省它是否支持给定的方法。

然后,当我们想要调用特定方法时,检查符合对象是否支持该方法,如果是,则执行调用该方法所需的必要计算。我试过这个代码 -

  @objc protocol FancyViewDelegate : NSObjectProtocol {
      optional func fancyView(view: UIView, didSelectSegmentAtIndex index: Int)
      optional func fancyView(view: UIView, shouldHighlightSegmentAtIndex index: Int) -> Bool
    }


    class FancyView: UIView {
      var delegate: FancyViewDelegate?

      private func somethingHappened() {
        if delegate?.respondsToSelector("fancyView:didSelectSegmentAtIndex") == true {
          let idx :Int  = 0 //Compute the index here
          delegate?.fancyView!(self, didSelectSegmentAtIndex: idx)
        }
      }
    }