Objective-C properties can be declared as either atomic (the default) or nonatomic. Understanding the distinction is critical, especially for multithreading and performance implications in iOS/macOS development.
Atomic
- Default behavior: If you don’t specify, a property is
atomic. - Thread safety: When you access (read or write) an
atomicproperty, Objective-C guarantees that you’ll always get a fully initialized value—even if multiple threads access it simultaneously. - How it works: The underlying getter and setter are automatically synchronized using a lock. Only one thread can execute a getter or setter at any moment, preventing simultaneous access.
- Performance: This adds locking overhead, so
atomicproperties may be slower—especially in high-frequency access scenarios. - Limitations: Only accessor methods (get/set) are “atomic.” If you perform compound actions (like read-modify-write), that remains unprotected. Thus,
atomicdoes not make your entire object thread-safe—just that one property’s getter/setter.
Example:
@property (atomic, strong) NSString *title;
Nonatomic
- Explicitly marked: You declare a property as
nonatomicif you do not require atomicity. - Thread safety: No automatic locking or synchronization is provided. The getter/setter can be executed by multiple threads simultaneously and may result in inconsistent or partially updated values if not externally protected.
- Performance:
nonatomicis faster because there’s no synchronization overhead. - Typical Use: In UI code, especially on iOS (where the main thread handles most properties),
nonatomicis recommended for performance.
Example:
@property (nonatomic, strong) NSString *title;
Key Points:
atomiconly guarantees the getter or setter returns a fully constructed object; it does not guarantee the operation or object is thread-safe overall.- Declarations like
@property (nonatomic, strong)…are more performant and are the norm for most Objective-C properties, especially in UI-related code. - For true thread safety of an object, always use explicit synchronization mechanisms (like GCD locks or
@synchronized) if compound/multi-step state is touched across threads.
In summary:
Use atomic only if you have a very specific need for atomicity in multithreaded environments. Otherwise, for almost all iOS/macOS development, prefer nonatomic for improved performance, but always manage thread safety explicitly if required.
