簡體   English   中英

無法將self(實現協議)傳遞給類實例化的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
}

我有一個實現此協議的類

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

所有字符都在這里對我來說很好,現在在另一個類我實現FooProtocol與someType = MyType ,然后當我嘗試初始化Foo與類T = MyType通過將self在的init方法Foo類我得到一個編譯錯誤,我這里做錯了什么?

錯誤信息:

“無法使用類型為(_dep: NSObject -> () -> MyView)的參數列表調用init”

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對象,因此從技術上講應該可以嗎?

實際上,這似乎與您的泛型或協議一致性無關。 只是您要在初始化self之前嘗試在屬性分配中訪問self (初始化過程中分配了默認屬性值)。

因此,解決方案是使用如下所示的惰性屬性:

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

現在,它將在首次訪問時創建,因此在初始化self之后會創建它。

在使用self的地方了解self的背景非常重要。 在這種情況下, self並不意味着MyView的實例。

您可以通過以下方法使其正常工作:

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

在不了解您要在這里做什么的情況下,我不能多說。

所以看起來像這樣

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之前對其進行了初始化,否則程序將崩潰。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM