Atomic vs. Non Atomic Properties Crash Course
Objective-C properties could be defined as atomic or nonatomic.
What is the difference between the two and how does Swift properties behave? Atomic or non atomic?
Defining a property as atomic will guarantee that a valid value will be returned. Notice that valid does not always mean correct (more on that in the next section of this post).
This also does not mean that atomic properties are thread safe. Different threads can attempt to write and read a the same time. One of two values will be returned — the value before the change or the value of the change
Atomic properties suffer from minor performance hit due to locking and unlocking before and after setting/getting a value.
Atomic is the default behavior for properties — this is what you get if you don’t specify anything.
Atomic Properties and Threads Example
Let’s say we have an atomic property:
point = CGPoint(x: 10, y: 10)
In our app we have three threads that are simultaneously trying to access our point property.
- Thread A tries to read the CGPoint property
- Thread B is setting point = CGPoint(x: 1, y: 1)
- Thread C is setting point = CGPoint(x: 5, y: 5)
The big question is — what will be returned to thread A?
One of the following three values:
(x = 10, y = 10)
(x = 1, y = 1)
(x = 5, y = 5)
Another question we can ask is — what will be the final value of the point property?
One of the following two values:
(x = 1, y = 1)
(x = 5, y = 5)
Non Atomic Properties
Non atomic properties has no guarantee regarding the returned value. It can be the correct value, a partially written value or even some garbage value.
As most things that are not safe — this comes with enhanced speed of accessing this properties.
Non Atomic Properties and Threads Example
Let’s take the same point property and the same three threads doing exactly the same things as in the atomic properties threads example.
What will be returned to thread A?
Unknown! It can be one of the three different values in the previous example. It could even be (x=5, y=1) two threads are trying to set the value at the same time. The value has been partially written and we are getting back a partially written value.
How does the Objective-C runtime do this?
Let’s look at the “set value” method for the Objective-C run time.
Notice how non atomic properties are directly setting the value of the property while atomic property are using locks to protect the set operation.
What about Swift?
Swift properties are non atomic by default.
But — According to Apple’s Using Swift with Cocoa and Objective-C (Swift 3.1):
Atomicity property attributes (atomic and nonatomic) are not reflected in the corresponding Swift property declaration, but the atomicity guarantees of the Objective-C implementation still hold when the imported property is accessed from Swift.
So — if you define an atomic property in Objective-C it will remain atomic when used by Swift.