1、将protocol的方法声明为mutating
2、Protocol Extension
3、可选接口和接口扩展
4、protocol组合
5、delegate
1、将protocol的方法声明为mutating
- mutating关键字用于修饰protocol中的方法
- 在Swift中protocol不仅可以被class遵守,还可以被struct、enum实现,protocol中的方法前面加入了该关键字,那么在该方法的实现中可以修改struct和enum中的成员变量,在class中是默认可以修改的。
2、Protocol Extension
- 现在我们可以对一个已有的protocol进行扩展,而扩展中实现的方法将作为实现扩展的类型的默认实现。也就是说,protocol extension为protocol中定义的方法提供了一个默认的实现。
- 如果类型推断得到的是实际的类型:
a 那么类型中的实现将被调用;如果类型中没有实现的话,那么接口中扩展中的默认实现将被使用 - 如果类型推断得到的是接口,而不是实际类型:
a 并且方法在接口中进行了定义,那么类型中的实现将被调用;如果类型中没有实现,那么接口扩展中的默认实现被使用
b 否则(也就是方法没有在接口中定义),扩展中的默认实现将被调用
3、可选接口和接口扩展
- Swift中的protocol的所有方法都是必须被实现的。原生的Swift protocol里没有可选项,所有定义的方法都是必须实现的。如果我们想要像Objective-C里那样定义可选的接口方法,就需要将接口本身定义为Objective-C的,也即在protocol定义之前加上@objc。另外关键字由原来的@optional变成optional,且每一个可选方法前都要加optional关键字。
@objc protocol OptionalProtocol {
optional func optionalMethod() //可选
func necessaryMethod() //必须
optional func anotherOptionalMethod() //可选
}
- 一个不可避免的限制是,使用@obj修饰的protocol就只能被class实现了,也就是说,对于struct和enum类型,我们是无法令他们所实现的接口中含有可选方法或者属性的。另外,实现他的class中的方法还必须也被标注为@objc,或者整个类就是继承自NSObject。这对我们写代码来说是一种让人郁闷的限制。
- 在Swift 2.0中protocol可选方法的替代方案是可以在protocol extension中将可选方法进行默认实现。
4、protocol组合
- 接口组合的标准语法如下:
protocol<ProtocolA, ProtocolB, ProtocolC> //尖括号内是具体接口的名称,这里表示将名称为ProtocolA,ProtocolB以及ProtocolC的接口组合在一起的一个新的匿名接口。实现这个匿名接口就意味着要同时实现这三个接口所定义的内容。 - protocol组合是可以使用typealias来命名的:
typealias PetLike = protocol<KittenLike, DogLike>
typealias CatLike = protocol<KittenLike, TigerLike>
- 实现多个接口时接口内方法冲突的解决方法
protocol A {
func bar() —> Int
}
protocol B {
func bar() —> String
}
class Class: A, B {
func bar() —> Int
{
return 1
}
func bar() —> String{
return “Hi”
}
}
只要在调用前进行类型转换就可以了
let instance = Class()
let num = (instance as A).bar() //1
let str = (instance as B).bar() //“Hi”
5、delegate
- Swift的protocol是可以被除了class以外的其他类型遵守的,而对于像struct或是enum这样的类型,本身就不通过引用计数来管理内存,所以也不能用weak这样的ARC的概念来进行修饰。
- 要想在Swift中使用weak delegate,我们就需要将protocol限制在class内。
- 一种做法是将protocol声明为OC的,这可以通过在protocol前面加上@objc关键字来达到,OC的protocol都只有类能实现,因此使用weak来修饰就合理了。
@objc protocol MyClassDelegate {
func mehotd()
}
- 另一种可能更好的办法是在protocol声明的名字后面加上class,这可以为编译器显式的指明这个protocol只能由class来实现。
protocol MyClassDelegate: class {
func method()
}
网友评论