我们说我有以下基础设施:
protocol Naming {
var printer: Printer { get }
var name: String { get }
}
extension Naming {
var name: String { return "\(type(of: self))" }
func printName() {
printer.print(name)
}
}
protocol Printer {
func print(_: String)
}
我有一个公开名称和打印机的协议,用于打印名称。
现在,尝试关注MVC,我添加了这些:
protocol ModelInjectable {
associatedtype Model
var model: Model { get }
}
extension Naming where Self: ModelInjectable, Self.Model: Naming {
var printer: Printer { return model.printer }
var name: String { return model.name }
}
允许视图控制器指定它们允许模型,并且在这种情况下允许它们通过简单地将协议一致性转发到模型来符合Naming
。
这是一个简单的VC:
class MyViewController: UIViewController, ModelInjectable, Naming {
let model: MyModel
required init(model: MyModel) {
self.model = model
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError()
}
}
当我尝试为模型使用协议时出现问题:
struct MyModel: Naming {
let printer: Printer
}
按预期工作,但是
protocol MyModel: Naming {
}
给出了编译错误:
错误:输入' MyViewController'不符合协议'命名' class MyViewController:NSViewController,ModelInjectable,Naming {
注意:候选人具有不匹配的类型'打印机' var printer:Printer {return model.printer}
注意:协议要求属性' printer'使用'打印机&#39 ;;你想添加一个存根吗? var printer:Printer {get}
据我所知,只有在使用具体类型时,编译器才会使用extension Naming where Self: ModelInjectable, Self.Model: Naming
扩展名。使用协议引用并不能解决问题。这是编译器的限制,还是我错误地使用了该功能?
答案 0 :(得分:1)
与...不同Objective-C协议,Swift协议不符合自身。因此,0
不符合协议扩展的protocol MyModel: Naming
约束。