当前位置: 首页 > 面试题库 >

Swift-惰性var线程安全吗?

夔光霁
2023-03-14
问题内容

也许这个问题需要一些上下文。

我一直在使用Core Data在持久层上进行工作,发现Core
Data不是线程安全的,因此仅需要NSManagedObjectContext限制在每个线程中。

因此,我的方法是创建自定义后台线程NSManagedObjectContext,以执行获取,保存等操作,同时还要创建主线程NSManagedObjectContext,该线程将用于NSManagedObject从获取的线程中获取NSManagedObjectId并将其传递给调用者方法。

默认情况下,Xcode的生成与核心数据模板的代码中使用lazy var的所有NSManagedObjectContextNSManagedObjectModel等等。

所以我的问题是是否

使用lazy var实例化方法来创建NSManagedObjectContext,前提是lazy var为每个尝试访问的线程初始化一个对象(不是线程安全的吗?)

要么

NSManagedObjectContext在每个线程中声明单独的变量,并使所有与线程相关的方法引用两个不同的变量NSManagedObjectContext,它们lazy var是线程安全的(?),并且在访问该线程时与线程无关仅创建一次。

先感谢您!

编辑:任何在Core Data并发问题上苦苦挣扎的人,本文都会列出一个非常好的设计模式,正如Aaron在下面的评论中指出的那样!


问题答案:

从Swift编程语言:属性:

如果lazy多个线程同时访问带有修饰符的属性,并且该属性尚未初始化,则不能保证该属性仅被初始化一次。

lazy var不是线程安全的。您可以使用

  • dispatch_once (在应用的整个生命周期内运行一次)
  • 常数(let
  • 嵌套的struct模式(通常用于单例)

为了线程安全。

您还可以使用使用自己的锁定,NSRecursiveLock但是效率可能不如dispatch_once



 类似资料:
  • 问题内容: 初始化的优点或区别是什么? 而不是简单地使用: (是:) 非常感谢您的帮助。 问题答案: 惰性存储属性vs存储属性 具有惰性属性而不是存储属性有一些优点。 仅当您读取该属性时,才执行与lazy属性关联的闭包。因此,如果出于某种原因未使用属性(可能是由于用户的某些决定),则可以避免不必要的分配和计算。 您可以使用存储属性的值填充惰性属性。 您可以在内部使用惰性属性关闭

  • 1.1 定义 线程安全:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协调,这个类都能表现出正确的行为,那么就称这个类是线程安全的。 线程不安全:如果一个类对象同时可以被多个线程访问,如果不做同步处理,可能表现出线程不安全现象(抛出异常、逻辑错误)。 1.2 原子性 1.2.1 定义提供了互斥访问,同一时刻(时间段)只能有一

  • 我使用StringRedisTemplate向redis添加条目,如下所示。 我必须显式添加线程安全功能吗?我在StringRedisTemplate或RedisTemplate源中没有看到任何synchronize关键字。

  • 问题内容: 每个程序员都不容易理解惰性线程安全的单例实例,因此我想在我们的企业框架中创建一个可以完成此工作的类。 你怎么看待这件事?你看到不好的东西吗?在Apache Commons中有类似的东西吗?我怎样才能使它更好? Supplier.java LazyThreadSafeInstantiator.java 用法示例: 谢谢 问题答案: 惰性线程安全的单例实例对于每个编码器来说都不容易理解 不

  • HashMap的底层算法采用了链地址法来解决哈希冲突 哈希表 在数据结构中有一种称为哈希表的数据结构,它实际上是数组的推广。如果有一个数组,要最有效的查找某个元素的位置,如果存储空间足够大,那么可以对每个元素和内存中的某个地址对应起来,然后把每个元素的地址用一个数组(这个数组也称为哈希表)存储起来,然后通过数组下标就可以直接找到某个元素了。这种方法术语叫做直接寻址法。这种方法的关键是要把每个元素和

  • 问题内容: servlet是线程安全的吗?例如,如果我打开5个不同的浏览器并向容器中的一个servlet发送请求,它是否仍然是线程安全的,我特别指的是方法 问题答案: 您的问题可以归结为: 正在从同一对象线程safe上的多个线程调用方法 。答案是: 取决于 。如果您的对象(让它成为servlet)是无状态的或仅具有字段,则这是完全线程安全的。局部变量和参数是线程局部的(驻留在堆栈上,而不是堆上)。