当前位置: 首页 > 知识库问答 >
问题:

在初始化闭包时访问“self”

袁永贞
2023-03-14

在 Swift 3 中,dispatch_once函数被删除,迁移指南建议使用初始化闭包:

让myGlobal = { … global包含对闭包调用的初始化…}()

_ = myGlobal //使用myGlobal只会在首次使用时调用初始化代码。

我想从初始化闭包中访问“Self”实例变量,如下所示:

class SomeClass {
    var other = SomeOtherClass()
    
    let initialize: () = {
        // self.other - this doesn't work, complains about unresolved identifier 'self'
        // how to access self.other here?
    } ()

    func doSomething() {
        // initialize will only be called once
        initialize
    }
}

为什么“自我”在闭包中是不可接近的,如何才能使它成为现实?

共有2个答案

梁和颂
2023-03-14

创建“SomeClass”类的实例时,它将首先在该实例上创建所有变量和常量。在这段时间内,自我可能不会完全初始化,因为它可能在设置过程中进行了一半。因此,在初始化步骤完成之前,self不可用。

在这个例子中,他们谈论的是一个没有自我概念的全局变量,或者类中的一个静态常量也没有自我概念。

如果需要实例方法/变量,您可以:

a)使它成为一个懒惰的变种喜欢

lazy var initialise : ()->Void = { 
    return {
        // can access self here
    }    
}()

它将在您第一次调用它时创建,而不是在初始化期间。当然,这样会丢失常量,并且您必须存储闭包,这很浪费,因为您只执行它一次。

b)将代码放在init方法中:

init() {
    // if your class doesn't have a super class, you can access self.other here. 
    // If it does have a super class (like NSObject) you must first call super.init() here to complete the initialisation. 
    // This can only be done after all other variables have been set.
}
於功
2023-03-14

这个引用的迁移指南示例具有误导性,因为它与全局变量相关。

初始化类时,立即调用实例let常量的闭包(一次)。这就是为什么它不能使用在同一级别上声明的其他变量的原因。

你能做的就是初始化< code>initialize(变量名不是最好的;-))懒洋洋地。闭包也只调用一次,但是——正如指南所描述的——只在第一次使用时调用。

class SomeClass {
  let other = SomeOtherClass()

  lazy var initialize : () = {
    let test = self.other
    test.doSomething()
  }()

  func doSomething() {
    // initialize will only be called once
    _ = initialize
  }
}
 类似资料:
  • 我试图为Dropwizard创建一个调度作业,该作业每分钟运行一次,并查询数据库中的值。 为此,我需要在< code>initialize()阶段注册一些Dao和一个服务,如下所示: JDBI需要Dropw的和配置对象。 是否可以在这个阶段访问这些,以便正确设置我的依赖项?

  • 问题内容: 情况: Go程序包 A 由3个文件组成,每个文件中我都使用另一个程序包 B 中的函数。我必须在每个文件的开头导入包 B。 题: 程序包 B 实际上是初始化3次还是仅初始化1次? 问题答案: 简短答案:初始化仅执行一次。 长答案:引用相关的规范部分- 程序执行: 通过为所有包级变量分配初始值,然后使用名称和签名调用任何包级函数来初始化不导入的包 在其来源中定义。名称为package-sc

  • 必需的初始值设定项的访问控制规则似乎与未指定必需的规则不同。为什么?

  • 问题内容: 我正在尝试使用从Web服务接收的以下字符串初始化JSONObject: 它似乎是有效的json(它在jsonlint.com中进行了验证),但是使用它初始化JSONObject时,我得到了: 有人可以帮忙吗? 谢谢 问题答案: 似乎您正在尝试从带有额外引号的String实例化它。您需要删除包装引号(我不使用您的字符串,而是给出一个示例使其更清楚): 还行吧: 这不是:

  • 问题内容: 我在我的应用程序中使用ArrayList。 我想知道从Singleton类初始化ArrayList的确切过程。 该数据将在其他一些活动中使用。 有人可以帮助了解Singleton课堂吗? 问题答案: 这是创建单例类的方法: 任何需要调用arrayList的地方都可以: 要将元素添加到数组,请使用: 要么

  • 据我所知,在Java11中,这两个操作可以在一行中完成,不是吗?