Are Swift variables atomic?
In Objective-C you have a distinction between atomic and nonatomic properties:
@property (nonatomic, strong) NSObject *nonatomicObject;
@property (atomic, strong) NSObject *atomicObject;
From my understanding you can read and write properties defined as atomic from multiple threads safely, while writing and accessing nonatomic properties or ivars from multiple threads at the same time can result in undefined behavior, including bad access errors.
So if you have a variable like this in Swift:
var object: NSObject
Can I read and write to this variable in parallel safely? (Without considering the actual meaning of doing this).
Solution 1:
It's very early to assume as no low-level documentation is available, but you can study from assembly. Hopper Disassembler is a great tool.
@interface ObjectiveCar : NSObject
@property (nonatomic, strong) id engine;
@property (atomic, strong) id driver;
@end
Uses objc_storeStrong
and objc_setProperty_atomic
for nonatomic and atomic respectively, where
class SwiftCar {
var engine : AnyObject?
init() {
}
}
uses swift_retain
from libswift_stdlib_core
and, apparently, does not have thread safety built in.
We can speculate that additional keywords (similar to @lazy
) might be introduced later on.
Update 07/20/15: according to this blogpost on singletons swift environment can make certain cases thread safe for you, i.e.:
class Car {
static let sharedCar: Car = Car() // will be called inside of dispatch_once
}
private let sharedCar: Car2 = Car2() // same here
class Car2 {
}
Update 05/25/16: Keep an eye out for swift evolution proposal https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md - it looks like it is going to be possible to have @atomic
behavior implemented by yourself.
Solution 2:
Swift has no language constructs around thread safety. It is assumed that you will be using the provided libraries to do your own thread safety management. There are a large number of options you have in implementing thread safety including pthread mutexes, NSLock, and dispatch_sync as a mutex mechanism. See Mike Ash's recent post on the subject: https://mikeash.com/pyblog/friday-qa-2015-02-06-locks-thread-safety-and-swift.html So the direct answer to your question of "Can I read and write to this variable in parallel safely?" is No.
Solution 3:
It is probably to early to answer this question. Currently swift lacks access modifiers, so there is not obvious way to add code which manages concurrency around a properties getter / setter. Furthermore, the Swift Language doesn't seem to have any information about concurrency yet! (It also lacks KVO etc ...)
I think the answer to this question will become clear in future releases.