面向?qū)ο? 聲明一個(gè)人的類 -> 具有吃/跑/睡 的屬性或方法
這個(gè) 吃/跑/睡的方法只在這一個(gè)人當(dāng)中有效. 當(dāng)很多類都有這三個(gè)方法的時(shí)候我們會(huì)抽取一個(gè)具有這三個(gè)方法的父類. 一個(gè)工程當(dāng)中有許多個(gè)父類與子類,這是OOP的特點(diǎn): 封裝與繼承. 但是繼承會(huì)增加類與類之間的耦合度,父類中的代碼變得不可撼動(dòng),牽一發(fā)動(dòng)全身.也增加了復(fù)雜度.
面向協(xié)議: 聲明一個(gè)人的類(或結(jié)構(gòu)體) -> 遵守吃/跑/睡 的協(xié)議間接擁有這些方法
一個(gè)工程當(dāng)中會(huì)有多個(gè)含有不同方法的協(xié)議,聲明一個(gè)類,需要什么方法就到這對協(xié)議里面去找. 一個(gè)協(xié)議可以被多個(gè)類遵循而且大大降低了耦合度,像一塊塊的組件. Swift的協(xié)議當(dāng)中可以提供方法的實(shí)現(xiàn),因此有了POP.
OOP像是一棵樹,上面的分支依賴著下面的主干..修改主干會(huì)影響到分支.
POP像是一輛車,輪胎,車窗,發(fā)動(dòng)機(jī),都是一個(gè)個(gè)的組件,可單獨(dú)修改拆卸.
- - - 使用協(xié)議抽取從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
}
}
因?yàn)橛美^承和類別的時(shí)候無法使用Self確定當(dāng)前調(diào)用的class.編譯器報(bào)錯(cuò)
- - - 使用協(xié)議封裝粒子動(dòng)畫..遵守協(xié)議的控制器可以開啟粒子動(dòng)畫
/// 提供粒子動(dòng)畫的協(xié)議
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)
//彈出個(gè)數(shù)
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()
}
}