Atomic vs Nonatomic

Day 5

In an earlier post I discussed the difference between (strong) and (weak) attributes for a property. In this post I will discuss the difference between (atomic) and (nonatomic).

Atomic

Atomic is the default behaviour for a property; by not explicitly setting the above property as nonatomic, it will be atomic.

An atomic property adds a level of thread safety when getting or setting values. That is, the getter and setter for the property will always be fully completed regardless of what other threads are doing. The trade-off is that these properties will be a little slower to access than a nonatomic equivalent.

Nonatomic

Nonatomic properties are not thread safe, and will return their properties directly. This will be faster than atomic properties, but obviously carries some risk if precautions aren’t made.

When is it Appropriate to Use Nonatomic?

One thing I’ve noticed while following Objective-C tutorials and articles is that nonatomic is used most of the time. So if nonatomic is so risky, why is it used so often?

It’s all about performance. An atomic property’s getter and setter, conceptually, looks something like this:

Whereas a nonatomic property getter and setter looks something like this:

It’s easy to see how the nonatomic implementation is going to be more light weight, but it does mean you have a responsibility to ensure problems don’t arise. Some articles I’ve read recommend keeping things atomic until performance becomes a problem, while others recommend the opposite.

In any event, if you decide to create a nonatomic property, here are some tips for keeping things thread safe:

  • Use immutable objects where possible. For example, rather than creating an NSMutableArray, create an immutable NSArray. Whenever you need to add an object to it, create a mutable copy first and do what you need to do, then replace the entire property in one hit rather than tacking on another value to the end.
  • You can wrap potentially problematic sections of code with @synchronized.
  • UI code can always be nonatomic because UI code always happens on the main thread of the application.

Closing Comments

It’s posts like this one that make me glad I’ve created this blog. Before today, I sort of knew the difference between the two in large strokes, but it wasn’t until I sat down and wrote this post that I was forced to ensure I really understood what I was tying. I had to research and understand thread safety before I could confidently hit the publish button.

To be honest, even now I’m terrified someone is going to chew me out in the comments. Be gentle ;)

  • JonahWilliams
    I think everything above is correct but I want to add that I think atomic properties give a misleading sense of thread safety. Using atomic properties is sometimes necessary when writing thread safe classes but it is almost never sufficient. With atomic properties you have synchronized getters and setters so multiple threads acting on a single property will complete atomic operations. That's useful because you probably don't want a value to change while you're halfway through copying it in a getter. That's not the same as making a class thread safe. If I write a request queue an atomic "-requests" property is not going to magically be safe to access while another thread calls the "-addRequest:" or "-cancelAllRequests" methods I might add unless I do some extra work to make sure the shared state those all rely on is thread safe. Personally I would rather see properties default to nonatomic because that is clearly not thread safe whereas when I see an atomic property I have to start hunting in the class' documentation for some hint if it's use is actually thread safe or not.