Is Atomic property thread safe

if we define a property in the following way:

@property (atomic) NSString *latestObject; Can we assume that the read write to that value is thread safe? i.e the value will be correct. Or it is better to write our own setter/getter with Locks?

Answered by DTS Engineer in 794363022

Non-atomic properties are not thread safe. I was very clear about that earlier:

Nonatomic properties are not thread safe. That’s by definition
could you please provide a reproducible snippet of code that breaks thread safety … ?

No, sorry, I don’t have time for that.

what is the Apple definition of thread safety?

I don’t think Apple has a consistent definition of thread safety, which is why I’ve spent time on this thread coming up with a definition that we agree on.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

When defining a property like this — where you’re using a class, like NSString, that has a mutable subclass — it’s vital that you mark the property as copy. Without that, the property isn’t safe regardless of threading O-:

Assuming that, a property marked as atomic is… well… atomic. That is, you can read or write it from any thread and you’ll always get consistent behaviour. Specifically, a reader will always get a value that’s either the current value or a value that was current at some point in the past.

Is that “thread safe”? It depends on your definition of that term. My experience is that folks come to concurrency from different backgrounds, and their understanding of the term thread safe is based on that experience.

My experience is that atomic properties are rarely useful. Consider this classic example:

@property (atomic, copy, nonnull) NSString * familyName;
@property (atomic, copy, nonnull) NSString * givenName;

Each property is ‘thread safe’ but that doesn’t mean the object as a whole is. Someone who reads both properties might receive inconsistent values.

Now, rarely useful isn’t the same as never useful. Sometimes an atomic property is the right tool for the job. But, in general, my experience is that it’s better to manage concurrency as a higher level, which is what we’re doing with the Swift concurrency model.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

ok so lets define couple of things.

"thread safe" - lets define it as safe to use without crashing

"correctness of the value" - basically what you mentioned, a consistent behavior between right and reads.

Let's keep the discussion only to one property. In that case can we assume its thread safe and correctness of the value?

In that case can we assume its thread safe and correctness of the value?

Sure.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Sorry but I still have few follow up question.

  1. With the above definitions can I assume that

@property (nonatomic , copy, nonnull) NSString * familyName;

Will also be thread safe (no crash) and the value correctness in multi thread environment. My assumption arise coz from first look I would assume that the read/write occurs to the underhand ivar and the object is immutable but I am not 100% confident if there are any additional steps in the synthesized getter/setter

  1. From what I can see Apple interpretation of thread safety is the consistency of the data across the whole objets i.e in your case is the consistency between the familyName and givenName . am I correct?

@DTS Engineer

Any chance you can share your insight about the above question?

Nonatomic properties are not thread safe. That’s by definition, but if you want a concrete example of where things go wrong then consider your familyName example:

  1. Thread A sets the familyName property to some value. It’s a copy property, so the setter makes a copy and stores that reference in its ivar. Because it just made a copy, the ref count is 1.

  2. Thread B gets the property. The getter reads the ivar and starts to return it. At this point the thread is preempted.

  3. Thread A sets the property to nil. The setter clears the ivar and releases the value’s reference. The reference count goes to 0 and the system deallocates the value.

  4. Thread B resumes execution. The getter returns to the caller, which now uses a value that was deallocated in the previous step.

In an atomic property the getter adds a -retain / -autorelease pair to avoid this problem.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Can you please answer my questions as is in apple documentations its mentioned that NSstring is thread safety: Thread Safety Objects When Apple says thread safety what do they mean: is it: crash/ no crash or the correctness of the entire value (like you gave in the above example of 2 properties)?

if We look at the following property

@property (nonatomic, nonnull) NSString * familyName;

Without copy (I see no particular reason to set it as copy although the underline subclass is mutable, but lets assume we are not going to pass any mutable object to that property). If the following is read and written from multiple threads can it crash? can it have non correct value ? (what do you mean non thread safety in that context) From your last answer u described a case when it can crash (accessing a released object). Can you back up your answer with code snippet? Can you provide a code that will crash when you read/ write to the above property from different threads?

OK, let’s write some code…


@interface User1 : NSObject

@property (nonatomic, strong, readwrite) NSString * firstName;
@property (nonatomic, strong, readwrite) NSString * givenName;

@end

This is not thread safe because it allows the client to set the string properties to arbitrary subclasses of NSString. One of those subclasses is NSMutableString, and bad things will ensue if you mutate the string on one thread while accessing it on another.


@interface User2 : NSObject

@property (nonatomic, copy, readwrite) NSString * firstName;
@property (nonatomic, copy, readwrite) NSString * givenName;

@end

This is not thread safe because the properties are not atomic. This is the case that I covered in my previous post.


@interface User3 : NSObject

@property (atomic, copy, readwrite) NSString * firstName;
@property (atomic, copy, readwrite) NSString * givenName;

@end

This is thread safe up to a point. You can read and write the properties from arbitrary threads and not crash. However, you won’t necessary get coherent results, for example:

  1. Assume firstName and givenName are set to Napoleon and Bonaparte respectively.

  2. Thread A changes those to Arthur and Wellesley.

  3. Between the two writes it’s suspended, and thread B runs.

  4. Thread B reads the two properties and gets back Arthur and Bonaparte.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

@DTS Engineer

Thanks BUT that not what I am asking. I will try to make it more clear: GIVEN:

@interface User2 : NSObject
@property (nonatomic) NSString * firstName;
@end

AND firstName will NOT have assignment of ANY mutable subclasses like NSMutableString i.e the only assignment is of type NSString.

QUESTION: Will the following be a "thread safe" (For current context thread safe definition: NO crash AND correct Result).

If the following is NOT "thread safe" by the definition above could you please provide a reproducible snippet of code that breaks thread safety (not theoretical retain/release explanation)?

(a side question. what is the Apple definition of thread safety?)

Accepted Answer

Non-atomic properties are not thread safe. I was very clear about that earlier:

Nonatomic properties are not thread safe. That’s by definition
could you please provide a reproducible snippet of code that breaks thread safety … ?

No, sorry, I don’t have time for that.

what is the Apple definition of thread safety?

I don’t think Apple has a consistent definition of thread safety, which is why I’ve spent time on this thread coming up with a definition that we agree on.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Is Atomic property thread safe
 
 
Q