面向对象: 声明一个人的类 -> 具有吃/跑/睡 的属性或方法
这个 吃/跑/睡的方法只在这一个人当中有效. 当很多类都有这三个方法的时候我们会抽取一个具有这三个方法的父类. 一个工程当中有许多个父类与子类,这是OOP的特点: 封装与继承. 但是继承会增加类与类之间的耦合度,父类中的代码变得不可撼动,牵一发动全身.也增加了复杂度.
面向协议: 声明一个人的类(或结构体) -> 遵守吃/跑/睡 的协议间接拥有这些方法
一个工程当中会有多个含有不同方法的协议,声明一个类,需要什么方法就到这对协议里面去找. 一个协议可以被多个类遵循而且大大降低了耦合度,像一块块的组件. Swift的协议当中可以提供方法的实现,因此有了POP.
OOP像是一棵树,上面的分支依赖着下面的主干..修改主干会影响到分支.
POP像是一辆车,轮胎,车窗,发动机,都是一个个的组件,可单独修改拆卸.
- - - 使用协议抽取从Nib中加载View的代码 (父类和extension无法做到)
protocol LoadNibView {
}
extension LoadNibView where Self: UIView {
static func loadFromNib() -> Self {
return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.first as! Self
}
}
因为用继承和类别的时候无法使用Self确定当前调用的class.编译器报错
- - - 使用协议封装粒子动画..遵守协议的控制器可以开启粒子动画
/// 提供粒子动画的协议
protocol EmitterAnimate {
}
extension EmitterAnimate where Self: UIViewController{
func startEmitter(_ point: CGPoint){
let emitter = CAEmitterLayer()
emitter.emitterPosition = point
emitter.preservesDepth = true //三维效果
var cells = [CAEmitterCell]()
for i in 0 ..< 5{
let cell = CAEmitterCell()
// 速度
cell.velocity = 150
cell.velocityRange = 100
//方向
cell.emissionLongitude = -(CGFloat)(M_PI_2)
cell.emissionRange = CGFloat(M_PI_2 * 0.2)
//弹出个数
cell.birthRate = 4
// 生命
cell.lifetime = 3
cell.lifetimeRange = 1.5
// 透明度
cell.alphaSpeed = -0.4
// 大小
cell.scale = 0.7
cell.scaleRange = 0.2
cell.contents = UIImage(named: "good\(i)_30x30")?.cgImage
cells.append(cell)
}
emitter.emitterCells = cells
view.layer.addSublayer(emitter)
}
func stopEmitter() {
view.layer.sublayers?.filter({ $0.isKind(of: CAEmitterLayer.self)}).first?.removeFromSuperlayer()
}
}