I have an object with a property:
@interface Car
@property(strong) NSLicensePlate *licensePlate;
@end
I use the property in a method:
If you want to enjoy the atomic
behavior (which is the default behavior that you get because you didn't specify the nonatomic
qualifier) of this property, you must use the getter (self.licensePlate
or [self licensePlate]
), not use the ivar (_licensePlate
).
In general, it's usually prudent to use the getters and setters everywhere except (a) the init
method; and (b) and custom accessor methods. The overhead is negligible and you avoid spectrum of potential problems ranging from atomicity, memory semantics, KVO, future-proofing code in case you customize accessor methods at some future date, etc.
But, assuming you access your property only through the accessor methods (the getters and setters), the atomic
qualifier, as described by Programming with Objective-C: Encapsulating Data ensures that the pointer, itself, that you are retrieving/setting is will not be corrupted by another thread:
[Atomic] means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
In answer to your question, if the other thread changes the licensePlate
property, while the frobnicate
method is running on the other thread, that original object will not be released until that method returns.
But to be clear, the atomic
qualifier does not ensure thread safety. As the above guide goes on to warn us:
Note: Property atomicity is not synonymous with an object’s thread safety.
Consider an
XYZPerson
object in which both a person’s first and last names are changed using atomic accessors from one thread. If another thread accesses both names at the same time, the atomic getter methods will return complete strings (without crashing), but there’s no guarantee that those values will be the right names relative to each other. If the first name is accessed before the change, but the last name is accessed after the change, you’ll end up with an inconsistent, mismatched pair of names.This example is quite simple, but the problem of thread safety becomes much more complex when considered across a network of related objects. Thread safety is covered in more detail in Concurrency Programming Guide.
So, it might be thread-safe to use frobnicate
on one thread while doing other stuff on another thread, but it also might not. It depends upon all the different things that can be done with this license plate object. Because the protections offered by atomic
are so minimalist, we frequently will employ some synchronization (via GCD serial queue or GCD reader-writer pattern, or via any of the synchronization methods outlined in the Threading Programming Guide: Synchronization such as locks) to coordinate interaction from different threads.