原生的 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
注意:
如果考虑到Swift
与Objective-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)
}
}