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).
Atomic means only one thread accesses the variable (static type). Atomic is thread-safe, but it is slow. Nonatomic means multiple threads access the variable (dynamic type). Nonatomic is thread-unsafe, but it is fast. Follow this answer to receive notifications.
The atomic variable allows us to perform an atomic operation on a variable. Atomic variables minimize synchronization and help avoid memory consistency errors. Hence, it ensures synchronization. The atomic package provides the following five atomic variables: AtomicInteger.
This is possible because JavaScript is essentially single-threaded - given piece of code is always executed atomically and never interrupted by another thread running JavaScript. Your fetch() function will always be executed without any interruption.
Atomic operations are sequences of instructions that guarantee atomic accesses and updates of shared single word variables. This means that atomic operations cannot protect accesses to complex data structures in the way that locks can, but they provide a very efficient way of serializing access to a single word.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With