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

dispatch_once_t在Swift中不可用:使用懒惰初始化的全局变量代替[复制]

路雅懿
2023-03-14

我在迁移到Swift 3时遇到了dispatch_once_t问题。

根据苹果的迁移指南:

dispatch_once的自由函数在Swift中不再可用。在Swift中,您可以使用延迟初始化的全局或静态属性,并获得与dispatch_once提供的相同的线程安全和调用一次保证。示例:

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

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

所以我想迁移这段代码。所以在移民之前:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        Static.instance = CarsConfigurator()
    }

    return Static.instance!
}

迁移之后,按照苹果的指导方针(手动迁移),代码如下所示:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token = {0}()
    }

    _ = Static.token

    return Static.instance!
}

但是当我运行这个程序时,当访问return Static时,我会遇到以下错误。举个例子

致命错误:在展开可选值时意外发现nil

我从这个错误中看到,实例成员是nil,但为什么是这样呢?我的迁移有什么问题吗?


共有1个答案

濮君植
2023-03-14

尽管该代码在Swift 2中有效,但它过于冗长。在Swift 3中,苹果通过闭包强制您使用延迟初始化:

class CarsConfigurator {
    static let sharedInstance: CarsConfigurator = { CarsConfigurator() }()
}
 类似资料:
  • 问题内容: 我有一个初始化为的变量: 问题是,在某个时候,我需要重置此变量,以便在更改后可以再次初始化。但是如果我将类设置为可选的话,LLVM在尝试将它设置为时会给我一个错误。如果我只是使用将其重置在代码中的某个位置,它将最终显示为。 有没有一种方法可以使用并允许自己重置? 问题答案: 懒惰是明确的仅一次初始化。您要采用的模型可能只是按需初始化模型: 现在,只要是,它会被初始化并返回。可以通过设置

  • 问题内容: 创建单例的模式似乎是这样的: 但是我的问题是,如果Singleton构造函数执行的不是单元测试友好的操作,例如如何调用外部服务,jndi查找等,您如何使用这样的类进行单元化? 我想我可以像这样重构它: 现在的问题是,仅出于单元可测试性,我已强制将getInstance同步,因此仅出于测试方面,它将对实际应用程序产生负面影响。有没有解决的办法,由于Java中双重锁定模式的破坏性,似乎其他

  • 我在想Spring中bean的懒惰初始化。对我来说,这里的“懒惰”是否意味着当一个bean被引用时会被创建并不十分清楚。 我认为Spring中的延迟初始化支持是不同的。我认为这是一个基于“方法调用”的惰性创建。我的意思是,每当对该方法调用任何方法时,都会创建该方法。 我认为这可以通过创建特定bean的代理实例并对任何方法调用进行初始化来轻松解决。 我是否遗漏了一些东西?为什么没有实施?这个概念有什

  • 问题内容: 我有一个让我真正困惑的事情,特别是以下代码触发了编译器错误“ unresolved identifier self”,我不确定为什么会这样,因为懒惰意味着在使用该属性时,该类已经实例化了。我想念什么吗? 提前谢谢了。 这是代码 问题答案: 由于某种原因,如果惰性属性的初始值引用,则需要显式类型注释。在swift- evolution邮件列表中 提到了这一点,但是我无法解释 为什么 这样

  • 问题内容: 我正在努力理解为什么我在使用Swift的iOS项目中遇到此编译器错误。如果我创建以下类: 我在“初始化前使用了变量’self.c’” 这一行上收到编译器错误。 起初我以为这是因为编译器无法验证该方法是否无法访问,但是后来我尝试将init方法混入一点: 这次的错误是“在初始化之前使用了变量’self.b’”(在同一行上)。这表明编译器 是 能够检查其性能的方法访问,所以据我可以看到应该有

  • 问题内容: Java的设计者是否有任何理由认为不应为局部变量提供默认值?认真地讲,如果实例变量可以被赋予默认值,那为什么我们不能对局部变量做同样的事情呢? 问题答案: 声明局部变量主要是为了进行一些计算。因此,程序员决定设置变量的值,并且不应采用默认值。如果程序员错误地没有初始化局部变量并且使用默认值,则输出可能是一些意外值。因此,在使用局部变量的情况下,编译器将要求程序员在访问变量之前使用一些值