Swift 如何优雅的实现协议的可选方法

原生的 Swift protocol 里没有可选项,所有定义的方法都是必须实现的。

给自定义的协议中添加extension,在extension中对可选方法进行默认实现,这样遵守协议的对象就可以不用实现可选方法.
代码示例:

protocol OptionalProtocol {
    func optionalMethod()        // 可选
    func necessaryMethod()       // 必须
    func anotherOptionalMethod() // 可选
}

extension OptionalProtocol {
    func optionalMethod() {
        print("Implemented in extension")
    }

    func anotherOptionalMethod() {
        print("Implemented in extension")
    }
}

class MyClass: OptionalProtocol {
    func necessaryMethod() {
        print("Implemented in Class3")
    }

    func optionalMethod() {
        print("Implemented in Class3")
    }
}

let obj = MyClass()
obj.necessaryMethod() // Implemented in Class3
obj.optionalMethod()  // Implemented in Class3
obj.anotherOptionalMethod() // Implemented in extension

注意:

如果考虑到SwiftObjective-C混编,或者,所写的协议要支持Objective-C(可能是用Swift写的一个开源组件,同时支持Objective-C),那么Objective-C代码中的对象想要遵守Swift中自定义的协议,那么使用@objc关键字实现协议的可选方法是更好的选择

如果自定义了拦截器作为代理,实现了以下两个运行时方法,那么就不能使用协议的分类实现协议的可选方法,因为拦截器可能会优先选择分类的实现,而控制器作为代理,被作为第二选择,代码示例如下:

internal override func forwardingTarget(for aSelector: Selector) -> Any? {
    if pickerView!.responds(to: aSelector) {
        return pickerView
    } else if delegate != nil && delegate!.responds(to: aSelector) {
        return delegate
    } else {
        return nil
    }
}

internal override func responds(to aSelector: Selector) -> Bool {
    if pickerView!.responds(to: aSelector) {
        return true
    } else if delegate != nil && delegate!.responds(to: aSelector) {
        return true
    } else {
        return super.responds(to: aSelector)
    }
}

参考:Swift必备tips-王巍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容