假设我们在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 let
或guard let
使用类似的前缀签名绑定两个可选方法的实现。
答案 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)
}
}
}