Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - is lazy var thread-safe?

Maybe this question requires a bit of context.

I've been working on my persistence layer using Core Data and found out that Core Data isn't thread-safe and thus requires NSManagedObjectContext to be confined to each one thread only.

So my approach is to create custom background thread NSManagedObjectContext which executes fetching, saving etc, while also to create main thread NSManagedObjectContext which will be used to get NSManagedObject from fetched NSManagedObjectId and pass it to caller method.

By default, Xcode generates template code related to Core Data using lazy var for all NSManagedObjectContext, NSManagedObjectModel etc.

So my question is whether to

use the lazy var instantiation approach for creating NSManagedObjectContext, provided that lazy var initiates an object for each thread trying to access (not thread-safe?)

or

declare separate variables for NSManagedObjectContext in each thread and make all thread-related methods to reference two different NSManagedObjectContext provided that lazy var is thread-safe(?) and created only once when it is accessed regardless of thread.

Thank you in advance!

edit: Anyone who is struggling with Core Data concurrency issue, this article lays out a very nice design pattern to work with as pointed out by Aaron in the comment below!

like image 451
Daniel Shin Avatar asked Apr 21 '15 02:04

Daniel Shin


People also ask

When should I use lazy var Swift?

Lazy variables allow you to delay the initialisation of stored properties. This can be useful to only perform expensive work when it's actually needed. The different between lazy- and computed properties is important in cases you need to have calculations based on the current state of values.

Are Swift value types thread-safe?

Swift provides no thread-safety whatsoever (it does not have any concept of threads). You're responsible for synchronizing accesses to objects, including standard library types yourself, especially with standard library types.

Is Swift static variable thread-safe?

Static variables in swift are not thread-safe by default.

How do I make a Swift variable safe thread?

In Swift, any variable declared with the let keyword is a constant and, therefore, read-only and thread-safe. When a variable is declared as var it becomes mutable and not thread-safe unless the data type is specifically designed to be thread-safe when mutable.


1 Answers

From The Swift Programming Language: Properties:

If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there is no guarantee that the property will be initialized only once.

lazy var is not thread safe. You can use

  • dispatch_once (runs once per lifetime of the app)
  • a constant (let)
  • the nested struct pattern (typically used for singletons)

for thread safety. (See this question for some examples.)

You could also employ your own locking using NSRecursiveLock but that's probably not as efficient as dispatch_once.

like image 114
Aaron Brager Avatar answered Oct 19 '22 07:10

Aaron Brager