簡體   English   中英

帶有函數swift的惰性初始化變量

[英]Lazy initialized variable holding a function swift

關於如何對包含函數的類變量進行延遲初始化,我有一個問題。 在我正在研究的項目中-在視圖控制器中-我需要基於僅在創建視圖控制器后才知道的信息來運行功能。 因此,我想使用惰性初始化來解決此問題。 我想我可以用其他方法解決問題,但是現在我對我對延遲初始化不了解的東西感到好奇,因為我很難弄清楚如何獲取延遲初始化的變量來保存函數。 也就是說,如果可以做到的話。

這是我正在嘗試執行的一些示例代碼。 我希望能夠在TestClass的實例上調用talk() ,然后此實例(在本例中為tc )調用f() ,它取決於環境是foo還是bar

class TestClass {

    func foo() {
        println("foo")
    }

    func bar() {
        println("bar")
    }

    lazy var f: ()->() = {
        return foo
    }()

    func talk() {
        f()
    }
}

var tc = TestClass()
tc.f()

現在,它無法編譯,並且出現錯誤:

Playground execution failed: swiftTesting.playground:28:30: error: 'TestClass -> () -> ()' is not convertible to '() -> ()'
    lazy var f: ()->() = {

然后我試圖改變我的f懶VAR到:

    lazy var f: TestClass->()->() = {
        return foo
    }()

這再次不起作用,現在我得到了錯誤, Missing argument for parameter #1 in call

任何人都可以闡明如何使用包含函數的變量進行延遲初始化嗎? 我知道我可以通過不使用惰性初始化來解決此問題,但我希望有人可以幫助我了解在這種情況下我做錯了什么。 謝謝。

foo是一個實例方法,但是閉包通過不自動綁定到self來避免隱式捕獲self 您需要明確地說出self.foo

lazy var f: ()->() = {
    return self.foo
}()
tc.f()
// tc is leaked, see below

當您改用TestClass->()->() ,該方法未綁定任何內容,因此您需要為其提供一個實例。

lazy var f: TestClass->()->() = {
    return foo
}()
tc.f(tc)()  // Call f with tc to give it an instance, then call the result

首選看起來不錯,但實際上將阻止tc釋放。 foo綁定到self並將其存儲在self內部會導致一個參考循環。 為避免這種情況,您需要使用對自身的捕獲較弱的閉包。

lazy var f: ()->() = {
    [weak self] in
    self!.foo()  // ! because self is optional due to being weak
}  // no () here
tc.f()
// tc can be deallocated

您需要明確聲明self

lazy var f: ()->() = {
    return self.foo
}()

暫無
暫無

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

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