Cri*_*tik 9 protocols objective-c swift
我无法使用以下代码:
@objc protocol Child { }
@objc protocol Parent {
var child: Child { get }
}
class ChildImpl: Child {
func doSomething() { }
}
class ParentImpl: Parent {
let child = ChildImpl()
// this would solve the problem, however can't access the ChildImpl members
// that are not part of the protocol
// let child: Child = ChildImpl()
// as well as this, however maintaining two properties is an ugly hack
// var child: Child { return childImpl }
// private let childImpl = ChildImpl()
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
Playground执行失败:错误:Tests.playground:3:7:错误:类型'ParentImpl'不符合协议'Parent'类ParentImpl:Parent {^
Tests.playground:4:9:注意:候选人具有非匹配类型'ChildImpl'var child = ChildImpl()
基本上我有两个父子协议,以及两个实现这两个协议的类.但是,编译器抱怨说这ChildImpl不是一个Child,这不是真的.
如果我使用相关类型,我可以使错误消失 Parent
protocol Parent {
associatedtype ChildType: Child
var child: ChildType { get }
}
Run Code Online (Sandbox Code Playgroud)
但是,我需要将协议提供给Objective-C,并且还需要能够引用child作为实际的具体类型.
是否有一个解决方案,不涉及重写协议Objective-C,或不添加重复的属性声明只是为了避免这个问题?
简短的回答是否定的,当前的设计不适用于当前的 Swift 语言。
原因是var child: Child { get }协议要求在幕后创建了一个存在容器,例如ExistentialContainer<Child>. 因此,任何符合协议的类型也必须声明相同类型的存在容器,而不是ExistentialContainer<Subtype>.
似乎存在容器不是协变的,因此暂时需要使用问题和其他答案中描述的解决方法。