swift - 惰性初始化变量持有函数 swift

标签 swift oop uiviewcontroller lazy-initialization

我有一个关于如何对包含函数的类变量进行延迟初始化的问题。在我正在处理的项目中 - 在 View Controller 中 - 我需要根据只有在创建 View Controller 后才知道的信息来运行一个函数。因此,我想使用延迟初始化来解决这个问题。我想我可以用其他方式解决这个问题,但现在我很好奇我对延迟初始化的不理解,以至于我很难弄清楚如何获取延迟初始化的变量来保存函数。也就是说,如果可以的话。

这是我想要做的一些示例代码。我希望能够在 TestClass 的实例上调用 talk(),然后该实例(在本例中为 tc)调用 f() 根据具体情况,可以是 foobar

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 惰性变量更改为:

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

这又不起作用,现在我收到错误,调用中参数#1 缺少参数

任何人都可以阐明如何使用包含函数的变量进行延迟初始化吗?我知道我可以通过不使用延迟初始化来解决这个问题,但我希望有人可以帮助我理解我在这种情况下做错了什么。谢谢。

最佳答案

foo 是一个实例方法,但闭包通过不自动绑定(bind)到它来避免隐式捕获 self。您需要明确地说 self.foo

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

当您使用 TestClass->()->() 时,该方法未绑定(bind)到任何内容,因此您需要为其提供一个实例。

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

第一个选择看起来不错,但它实际上会阻止 tc 被释放。将 foo 绑定(bind)到 self 并将其存储在 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/

相关文章:

php - OO : Inheritance vs Service

ios - UISegmentedControl 作为 NavigationController

ios - 在 Swift 中存储数据的最有效方式

python - self 参数是如何神奇地传递给实例方法的?

swift - 如何在 Swift 后台一段时间后呈现 UIViewController?

javascript - Javascript 中的静态变量只设置一次

ios - 在 segues 之间切换 iOS 中的 UINavigationController 栏

ios - Segue 启动但 viewDidLoad 没有为新的 ViewController 触发

ios - 如何使用户无需在 URL 前键入 "http://"?

ios - 在 xcode ui test 中运行所有测试类