无法将自身(实现协议)传递给 class 实例化的 init 方法。(Swift)

Not able to pass self (which implements a protocol) to init method of a class instantiation.(Swift)

我有这样的协议

public protocol FooProtocol {
    associatedType someType

    func doFoo(fooObject:someType) -> Void
}

我有一个 class 实现了这个协议

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)
    }
}

到这里为止的一切对我来说都很好,现在在另一个 class 中,我使用 someType = MyType 实现 FooProtocol,然后当我尝试初始化 Foo class 时T = MyType 通过在 Foo 的 init 方法中传递 self class 我得到一个编译错误,我在这里做错了什么?

错误信息:

" Cannot invoke init with an argument list of type (_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)`
}

不符合 someType == MyType 的 FooProtocol,因为我正在尝试用 T == MyType 初始化一个 Foo 对象,这在技术上应该可行吗?

看来这行得通

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 在访问之前已初始化,否则程序将崩溃。

希望对您有所帮助。

理解self的上下文是非常重要的。在这种情况下,self 并不意味着 MyView.

的实例

你可以,但是通过这样做让它工作:

let fooInstant : Foo<String> = Foo.init(_dep : MyView())

如果不明白你想在这里做什么,我就不能多说了。

这实际上似乎与您的泛型或协议一致性没有任何关系。这只是您在 self 初始化之前尝试在 属性 赋值中访问 self (默认 属性 值在 期间被赋值 初始化).

因此,解决方案是使用惰性 属性,如下所示:

lazy var fooInstant : Foo<MyType> = Foo(_dep : self)

这将在首次访问时创建,因此在 self 初始化后创建。