What is the difference between atomic and nonatomic attributes in Objective-C property declarations?
What do atomic and nonatomic mean in property declarations?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
What is the operational difference between these three property declaration styles?
The key difference between atomic and nonatomic attributes in Objective-C property declarations lies in thread safety guarantees and performance characteristics. Atomic properties provide thread-safe access by using locks to ensure that getter and setter operations complete fully before allowing other threads to access the property, while nonatomic properties offer faster performance but without thread safety protections, allowing multiple threads to potentially access the property simultaneously.
Contents
- Core Differences Explained
- Thread Safety Implications
- Performance Considerations
- Practical Usage Guidelines
- Implementation Details
- Default Behavior
Core Differences Explained
The three property declaration styles you’ve shown have important functional differences:
@property(nonatomic, retain) UITextField *userName; // Explicit nonatomic
@property(atomic, retain) UITextField *userName; // Explicit atomic
@property(retain) UITextField *userName; // Default behavior (atomic)
Atomic Properties (the third declaration and the explicit second one):
- Use locking mechanisms (typically NSLock) to ensure thread safety
- Guarantee that a complete value is always returned from the getter or set by the setter
- Provide robust access in multithreaded environments
- Are the default behavior when no atomicity specifier is given
Nonatomic Properties (the first declaration):
- Don’t implement any thread safety mechanisms
- Allow multiple threads to access the property simultaneously
- Offer better performance due to the absence of locking overhead
- Can result in inconsistent values if accessed concurrently
Key Insight: According to Apple’s documentation, “Properties are atomic by default so that synthesized accessors provide robust access to properties in a multithreaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.”
Thread Safety Implications
Atomic Properties:
- Ensure that getter/setter operations are atomic
- Prevent reading partial or garbage values during concurrent writes
- The Mozilla Developer Network explains that atomic properties “guarantee that a whole value is always returned from the getter or set by the setter, regardless of other thread activities”
- However, they don’t make the entire object thread-safe - only the individual property access
Nonatomic Properties:
- Multiple threads can simultaneously read and write values
- Risk of reading intermediate or corrupted values during concurrent operations
- As noted in Stack Overflow discussions, “Thread B releases object. Thread A goes boom” in scenarios where nonatomic properties are accessed concurrently
| Thread Safety Aspect | Atomic | Nonatomic |
|---|---|---|
| Read consistency | ✓ Protected | ⚠️ Risk of partial reads |
| Write atomicity | ✓ Protected | ⚠️ Risk of corruption |
| Overall object safety | ⚠️ Limited protection | ❌ No protection |
| Performance impact | Slower due to locks | Faster |
Performance Considerations
Atomic Properties:
- Slower performance due to locking overhead
- Each access requires acquiring and releasing locks
- As Repeato’s analysis notes, “Atomic: Ensure thread-safety by locking the thread using NSLOCK”
- Performance penalty is typically noticeable in high-frequency access scenarios
Nonatomic Properties:
- Faster performance due to direct value access
- No locking mechanism overhead
- As iOS Dev Hub explains, “nonatomic properties are more performant and are the norm for most Objective-C properties, especially in UI-related”
Practical Performance Impact:
- For UI-related properties (which typically run on the main thread), nonatomic is preferred
- For background threads accessing shared data, atomic provides basic protection
- The performance difference is generally negligible for infrequently accessed properties
Practical Usage Guidelines
When to Use Atomic Properties:
- When working with shared data in multithreaded environments
- When you need to prevent reading partial or garbage values
- For properties that are accessed concurrently and require basic consistency
When to Use Nonatomic Properties:
- UI-related properties (most views and controls)
- Performance-critical code paths
- Properties accessed primarily from a single thread
- When you implement custom thread safety mechanisms
Expert Recommendation: According to Nabeel Writes, “By default all properties are atomic” but “non atomic = is faster than atomic because UI Related all task work on main Thread so why we use atomic so Keep it non-atomic”
Implementation Details
Atomic Property Implementation:
- Uses synchronization locks (NSLock or similar)
- The getter typically looks like this:
- (UITextField *)userName {
@synchronized(self) {
return _userName;
}
}
- The setter includes similar locking to ensure atomic operation completion
Nonatomic Property Implementation:
- Direct property access without synchronization
- Getter simply returns the instance variable:
- (UITextField *)userName {
return _userName;
}
- Setter performs direct assignment:
- (void)setUserName:(UITextField *)userName {
_userName = userName;
}
Important Clarification: As Yogev Sitton explains, “Atomic does not mean thread safe” - it only guarantees that individual property access operations are atomic, not that the entire object is thread-safe.
Default Behavior
Implicit Atomic Declaration:
- Properties declared without explicit atomicity specifiers are atomic by default
@property(retain) UITextField *userName;is functionally identical to@property(atomic, retain) UITextField *userName;- This default behavior ensures robust access in multithreaded environments
Why Atomic is Default:
- Provides better safety in multithreaded scenarios
- Prevents common concurrency issues like reading partial values
- As Apple’s documentation states, it provides “robust access to properties in a multithreaded environment”
Swift Integration Note: When importing Objective-C properties into Swift, the atomicity guarantees are preserved even though Swift doesn’t have atomic/nonatomic specifiers, as noted in Apple’s Swift documentation.
Conclusion
The differences between atomic and nonatomic properties in Objective-C boil down to thread safety guarantees and performance trade-offs:
-
Atomic properties provide thread-safe access through locking mechanisms, ensuring complete values are returned during getter/setter operations, but at the cost of performance overhead.
-
Nonatomic properties offer faster performance by eliminating locking, but without thread safety protections, making them suitable for single-threaded contexts like UI development.
-
Default behavior makes all properties atomic unless explicitly declared as nonatomic, providing robustness in multithreaded environments by default.
-
Practical guidance: Use nonatomic for most UI-related properties and performance-critical code, while atomic provides basic protection for shared data in multithreaded scenarios.
-
Important caveat: Even atomic properties don’t guarantee complete object thread-safety - they only ensure individual property access operations are atomic.
Sources
- Apple’s Official Documentation - Declared Properties
- Stack Overflow - What’s the difference between atomic and nonatomic attributes?
- Repeato - Understanding Atomic vs Nonatomic Attributes
- Medium - Atomic vs Non Atomic Properties Crash Course
- iOS Dev Hub - Atomic and Nonatomic Properties
- Nabeel Writes - Atomic vs Nonatomic Properties
- Apple Forums - Reference type properties atomic vs nonatomic
- Stack Overflow - Atomic properties vs thread-safe