@property(nonatomic, retain)( NSString *userName;
@property(atomic, retain) NSString *userName;
@property(retain) NSString *userName;
The last two are identical; "atomic" is the default behavior (
note that it is not actually a keyword; it is specified only by the absence of nonatomic --
atomic was added as a keyword in recent versions of llvm/clang).
Assuming that you are @synthesizing the method implementations,
atomic vs. non-atomic changes the generated code. If you are writing
your own setter/getters, atomic/nonatomic/retain/assign/copy are merely
advisory. (Note: @synthesize is now the default behavior in recent
versions of LLVM. There is also no need to declare instance variables;
they will be synthesized automatically, too, and will have an
_ prepended to their name to prevent accidental direct access).
With "atomic", the synthesized setter/getter will ensure that a
whole
value is always returned from the getter or set by the setter,
regardless of setter activity on any other thread. That is, if thread A
is in the middle of the getter while thread B calls the setter, an
actual viable value -- an autoreleased object, most likely -- will be
returned to the caller in A.
In
nonatomic, no such guarantees are made. Thus,
nonatomic is considerably faster than "atomic".
What "atomic" does
not do is make any guarantees
about thread safety. If thread A is calling the getter simultaneously
with thread B and C calling the setter with different values, thread A
may get any one of the three values returned -- the one prior to any
setters being called or either of the values passed into the setters in B
and C. Likewise, the object may end up with the value from B or C, no
way to tell.
Ensuring data integrity -- one of the primary challenges of multi-threaded programming -- is achieved by other means.