Ios Swift-lazy-var线程安全吗?
也许这个问题需要一些背景知识 我一直在使用核心数据处理持久层,发现核心数据不是线程安全的,因此需要将Ios Swift-lazy-var线程安全吗?,ios,multithreading,swift,core-data,Ios,Multithreading,Swift,Core Data,也许这个问题需要一些背景知识 我一直在使用核心数据处理持久层,发现核心数据不是线程安全的,因此需要将NSManagedObjectContext限制在每个线程中 因此,我的方法是创建自定义后台线程NSManagedObjectContext,它执行抓取、保存等操作,同时还创建主线程NSManagedObjectContext,它将用于从抓取的NSManagedObjectId中获取NSManagedObject,并将其传递给调用方方法 默认情况下,Xcode使用lazy var为所有NSMana
NSManagedObjectContext
限制在每个线程中
因此,我的方法是创建自定义后台线程NSManagedObjectContext
,它执行抓取、保存等操作,同时还创建主线程NSManagedObjectContext
,它将用于从抓取的NSManagedObjectId
中获取NSManagedObject
,并将其传递给调用方方法
默认情况下,Xcode使用lazy var
为所有NSManagedObjectContext
,NSManagedObjectModel
等生成与核心数据相关的模板代码
所以我的问题是是否
使用lazy-var
实例化方法创建NSManagedObjectContext
,前提是lazy-var
为尝试访问的每个线程启动一个对象(不是线程安全的?)
或
为每个线程中的NSManagedObjectContext
声明单独的变量,并使所有与线程相关的方法引用两个不同的NSManagedObjectContext
,前提是lazy var
是线程安全的(?),并且在访问它时只创建一次,而不考虑线程
提前谢谢你
编辑:任何正在与核心数据并发问题作斗争的人,都会提出一个非常好的设计模式来使用,正如Aaron在下面的评论中指出的那样 来自:
如果多个线程同时访问标记有lazy
修饰符的属性,并且该属性尚未初始化,则不能保证该属性只初始化一次
lazy var
不是线程安全的。你可以用
(在应用程序的每个生命周期中运行一次)dispatch\u once
- 一个常量(
)let
- 嵌套结构模式(通常用于单例)
您也可以使用
NSRecursiveLock
使用自己的锁定,但这可能不如dispatch\u once
高效,谢谢您的回答。那么这是否意味着lazy var
将为尝试访问其值的不同线程创建不同的实例?不,这意味着如果两个线程同时尝试访问它,第二个线程可能会收到一个部分初始化的对象。因为NSManagedObjectContext
不是线程安全的,所以不应该从不同的线程访问它。好的。因此,我应该为我希望使用的每个线程声明NSManagedObjectContext
的不同实例,并强制在后台线程中执行的方法只访问以前在同一后台线程中创建的NSManagedObjectContext
?谢谢。是的,不过如果你需要不止一个背景线程和一个主线程上下文,我会很惊讶。您可以看到他在哪里描述了一个良好的通用核心数据设置。@AaronBrager一句话,dispatch_曾经使用一个静态谓词,因此它将在应用程序的每个生命周期中运行一次。如果lazy变量是一个实例变量,那么您可能希望使用您提到的其他锁定技术或调度信号量。