1

假设我们在 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)
  }
}

编译器在我们面前跳跃:

在此处输入图像描述

我们可以改成somethingHappened()这样:

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

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

然而,正如你所看到的,我们冒着做大量工作的风险,只是为了在之后丢弃索引,因为委托没有实现可选方法。

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

4

1 回答 1

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)
        }
      }
    }
于 2015-12-04T12:21:37.543 回答