关于如何对持有函数的类变量进行延迟初始化,我有一个问题。在我正在处理的项目中——在视图控制器中——我需要基于创建视图控制器后才知道的信息运行一个函数。因此,我想使用懒惰的初始化来解决这个问题。我想我可以用其他方法来解决这个问题,但是现在我很好奇我对延迟初始化所不理解的是什么,我很难弄清楚如何得到一个延迟初始化的变量来保存一个函数。也就是说,如果可以的话。
下面是一些我要做的示例代码。我想能够对一个talk()的实例调用TestClass,然后这个实例(tc在本例中)调用f(),这取决于具体情况。

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: ()->() = {

然后我尝试将我的foolazy var更改为:
    lazy var f: TestClass->()->() = {
        return foo
    }()

这再次不起作用,现在我得到了错误,bar
有人能解释一下如何使用包含函数的变量进行延迟初始化吗?我知道我可以通过不使用懒惰的初始化来解决这个问题,但我希望有人能帮助我理解在这种情况下我做了什么错误。谢谢。

最佳答案

foo是一个实例方法,但是闭包通过不自动绑定来避免隐式捕获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

关于swift - 持有函数swift的惰性初始化变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31798655/

10-14 21:26
查看更多