Is it necessary to use @synchronized(self) in setters/getters on OS X?

If I remember correctly, whenever you implemented setters/getters for an atomic property (which is the what is typically used on OS X), the compiler used to warn you to use @synchronized.

It seems that the compiler no longer warns you about this. Is it no longer necessary to use

@synchronized in our setters/getters for atomic properties?

I don't recall it ever warning you. Indeed, the opposite has always been true — there was absolutely nothing ensuring that atomic accessors were atomic.

If you are implementing the accessors for an atomic declared property, you are responsible for ensuring the atomicity promised by the declaration. Atomicity may not be what you think. A lot of people have misconceptions about it. But, anyway, you can use @synchronized to implement it, but that's not the only way.


For scalar types of the size of a "word" in the CPU architecture (32- or 64-bit value), simple assignment and returning of the value is already atomic. For object pointers when building with ARC, simple assignment and returning of the value is also atomic. For object pointers when not building with ARC, you need some other synchronization mechanism and getters should retain within the synchronized code and autorelease before returning.


For larger scalar types (e.g. NSRect), you also have to use a synchronization mechanism. If your accessors do additional work, you also have to use a synchronization mechanism.


Personally, I make all of my properties nonatomic because atomic properties buy you almost nothing. For a class to be thread-safe requires much more and, once you do that, the atomicity of the properties becomes irrelevant.

I see. I always wrap code in the accessors that do extra work in @synchronized. I've been using atomic properties on the last several OS X apps I made because that seems to be what Apple recommends. Pretty much everywhere in Appkit, properties are atomic.


I could have sworn (though maybe I'm wrong) that when you manually implemented setters/getters for an atomic property the compiler would warn you to use @synchronized if you didn't a few Xcode versions ago...though maybe I dreamed it. I still do (use @synchronized), but I notice the compiler doesn't tell you to do so I was wondering if there was maybe some compiler magic going on and you know longer needed to do that. Seems like I got my answer though. Maybe the compiler never warned you to use @synchronized at all and I just dreamed it because I always thought that was the right thing to do.


I'm not determined enough to go downloading old Xcode versions and check if I get a warning. I'll just assume that we are responsible for ensuring atomic declared properties are atomic like you said when we implement setters/getters manually without any assistance from the compiler.

There are/were a couple of related warnings which may be what you remember. You can enable a warning that tells you when a property defaults to atomic because you didn't specify either 'atomic' or 'nonatomic'. You also used to (and may still) get a warning when you synthesize a property that defaults to atomic, and also define a custom getter or setter (but not both), since the synthesized and custom accessors are unable to use the same synchronization mechanism.


>> Pretty much everywhere in Appkit, properties are atomic.


And pretty much everywhere in UIKit, properties are non-atomic. I don't think Apple has ever recommended atomic properties (though they might have and I've forgotten). Instead, they chose to make properties atomic by default. This was an excellent decision for synthesized properties, but a dangerous decision for properties with custom accessors.


Also, keep in mind what Ken said, that atomicity is almost always unnecessary, and there is no atomicity attribute in Swift properties.

Yeah, on iOS all my properties are pretty much always nonatomic. On OS X I started using atomic properties awhile ago following Apple's lead even though it probably is unnecessary. I believe if you look at a lot of Apple's code that is cross-platform between iOS and OS X, Apple uses a macro to make the property nonatomic only on iOS but not OS X. I'm assuming there must be some logic behind that.

Is it necessary to use @synchronized(self) in setters/getters on OS X?
 
 
Q