我有一个像这样的协议
public protocol FooProtocol {
associatedType someType
func doFoo(fooObject:someType) -> Void
}
我有一个实现此协议的类
public class Foo<T> : FooProtocol {
private let _doFoo : (T) -> Void
init<P : FooProtocol where P.someType == T>(_dep : P) {
_doFoo = _dep.doFoo
}
public func doFoo(fooObject: T) {
_doFoo(fooObject)
}
}
这里的所有内容对我来说都很好,现在在另一个类中我使用someType = MyType
实现FooProtocol,然后当我尝试通过传递{{1}来Foo
类T = MyType
时在self
类的init方法中我收到编译错误,我在这里做错了什么?
错误讯息:
“无法使用类型
的参数列表调用initFoo
”
(_dep: NSObject -> () -> MyView)
与public class MyView : UIViewController, FooProtocol {
func doFoo(fooObject : MyType) {
...
}
// Here I want to initialize the Foo<T> class
let fooInstant : Foo<MyType> = Foo.init(_dep : self)
// I get the error message on the above line the error
// message reads "Cannot invoke init with an argument list
// of type `(_dep: NSObject -> () -> MyView)`
}
不能自我符合FooProtocol,并且由于我尝试使用someType == MyType
初始化Foo
对象,这在技术上应该可行吗?
答案 0 :(得分:4)
这实际上似乎与您的泛型或协议一致性无关。您只是在初始化self
之前尝试访问属性分配中的self
(在初始化期间为分配默认属性值)。
因此,解决方案是使用如下的惰性属性:
lazy var fooInstant : Foo<MyType> = Foo(_dep : self)
现在将在首次访问时创建,因此在初始化self
之后。
答案 1 :(得分:3)
了解self
在其使用地点的背景非常重要。在此上下文中,self
并不代表MyView
的实例。
然而,你可以这样做:
let fooInstant : Foo<String> = Foo.init(_dep : MyView())
如果不了解你想在这里做什么,我不能多说。
答案 2 :(得分:0)
看起来似乎有效
public class MyView : UIViewController, FooProtocol {
var fooInstant : Foo<MyType>!
public func initializeFooInstant(){
fooInstant = Foo.init(_dep : self)
}
func doFoo(fooObject : MyType) {
...
}
}
我认为系统不允许您访问self来初始化let属性,因为无法保证在初始化let属性时self已完全初始化。
在上面的例子中,您只需要确保在访问fooInstance之前初始化它,否则程序将崩溃。
希望这有帮助。