前言
现在很多公司的iOS新项目都开始用Swift来代替OC开发了,Swift带来的亮点和新功能很多,但我觉得最重要的一点是引导我们编程思想的改变,将我们在OC中用到的传统的面向对象编程思想OOP(object-oriented programming)向面向协议编程思想POP(protocol oriented programming)以及面向值的编程思想VOP(value-oriented programming)上转变,苹果也让我们开发者在编程的时候“从一个protocol开始,别从一个class开始”,再加上Swift的标准库中出现了比重很大的结构体struct和枚举类型enum,所以在Swift中灵活运用各种协议protocol和值类型value来实现功能既实用又优雅。而在Swift编程过程中无处不在的extension,不仅让我们在代码结构上发生了巨大改变,同时在编程理念上也与POP不谋而合。
extension
extension,顾名思义就是扩展,类似于OC中的category,但Swift中的extension功能却强大的多, 可以扩展class struc enum 甚至是protocol,来给他们:提供便利构造方法、增加运算属性、定义实例方法和类方法、定义下标、使已有的类型遵循协议等等。
现在有一个需求,A、B和C三个类,都需要扩展一个属性或者方法用处理同样的功能,OOP的做法:让A、B和C继承于一个基类D,然后给D中加上这个属性,或者当A、B和C三个类不方便继承自一个基类时,各自分别扩展一个属性。不过这样做感觉很死板的样子。
而面向协议编程POP的做法:写声明一个协议someProtocol,协议中声明这个属性,然后让A、B、C三个类都遵循这个someProtocol,分别再实现这个协议中的属性,如下所示:
//定义protocol
protocol someProtocol {
var clickCount: Int { set get }
func ClickEvent(action: String,value: NSNumber)
}
extension A: someProtocol{
var clickCount: int { set get }
func ClickEvent(action: String,value: NSNumber){
//实现代码
}
}
限定扩展 extesion...where..
而此时来了新的需求,需要给A类扩展另外一个属性,但B和C暂时不需要,大部分人的思维肯定是既然只有A需要,那我们就单独给A来扩展一个属性不就可以了吗,这样肯定行得通,但既然我们都已经走上了POP编程的道路,而且Swift也鼓励我们尽量用protocol来处理问题,那我们应该怎么在protocol上做文章呢?
首先我们想到了给someProtocol扩展一个属性,但这样不只是A能用,同样遵循了该协议的B和C,以及将来遵循这个协议的所有class、struct等等都扩展得到了这个属性,这从代码的逻辑性上来说是不严谨的,于是苹果在Swift2.0的时候加入了一个新功能,可以在给protocol扩展的时候添加限定,就是说在满足该限定条件(遵循另一个协议或者满足某个类型)下才能允许使用此扩展下的属性或方法, 而这个限定就是通过where来添加的, 先看代码:








