做定制点 (customization point)
class ViewController: UIViewController {
var sv = SVG.init(name: "333", age: 10)
sv.addCircle(center: CGPoint(x: 50, y: 50), radius: 10, fll: UIColor.red)
sv.drawSomething()
}
}
protocol DrawingContext {
mutating func addEllipse(rect: CGRect, fillColor: UIColor)
mutating func addRectangle(rect: CGRect, fillColor: UIColor)
mutating func addCircle(center: CGPoint, radius: CGFloat, fll: UIColor)
}
extension DrawingContext {
mutating func addCircle(center: CGPoint, radius: CGFloat, fll: UIColor) {
print("extension + DrawingContext + addCircle")
}
mutating func drawSomething() {
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
addRectangle(rect: rect, fillColor: .yellow)
let center = CGPoint(x: rect.midX, y: rect.midY)
addCircle(center: center, radius: 25, fll: .blue)
}
}
extension CGContext: DrawingContext {
func addEllipse(rect: CGRect, fillColor: UIColor) {
setFillColor(fillColor.cgColor)
fillEllipse(in: rect)
}
func addRectangle(rect: CGRect, fillColor: UIColor) {
setFillColor(fillColor.cgColor)
fill(rect)
}
}
class SVG: DrawingContext {
func addEllipse(rect: CGRect, fillColor: UIColor) {
print("")
}
func addRectangle(rect: CGRect, fillColor: UIColor) {
print("")
}
var name: String = ""
var age: Int = 0
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension SVG {
func addCircle(center: CGPoint, radius: CGFloat, fll: UIColor) {
print("extension + SVG + addCircle")
}
}
1、当 DrawingContext 协议没有 addCircle 方法时,sv 调用 addCircle 方法,和drawSomething 方法 打印结果如下
2、当 DrawingContext 包含 addCircle 方法时,sv 调用 addCircle 方法,和drawSomething 方法 打印结果如下
带有默认实现的协议方法在 Swift 社区中有时也叫做定制点 (customization point)。实现协议的类型会收到一份方法的默认实现,并有权决定是否要对其进行覆盖。标准库中这种定制点随处可见。一个例子,就是计算集合中两个元素之间距离的 distance(from:to:) 。也是一个定制点,这个方法默认 实现的时间复杂度是 O(n),因为它要遍历两个元素之间的所有位置,对于那些可以提供更有效率实现的类型,例如 Array,就可以重写默认的实现 了。