Home > Net >  Cocoa atomic properties and autorelease
Cocoa atomic properties and autorelease

Time:07-17

If I have an an atomic property in MyClass:

@property (readwrite, strong) NSMutableArray *atomicArray;

And a thread calls something like:

NSMutableArray* t = [myClassObject atomicArray];

Where is it documented that the object I get back is retained/autoreleased so that another thread can't call: [myClassObject setAtomicArray:otherArray]

and eliminate the object out from under me?

Another question mentioned this is true but without reference to any documentation from Apple.

Atomic properties vs thread-safe in Objective-C

CodePudding user response:

Assuming you are using ARC, the reference obtained in t is a strong one to the object that existed at the time you retrieved it. If some other thread replaces the object, t would still reference the original object, and that object would stick around until t goes out of scope.

However t being a mutable array, some other thread could get its own reference and modify the mutable array itself by adding and removing objects. Those changes would be visible to your t, because it is the same object.

That is important, because if you try to iterate over the array while some other thread modifies it, you may encounter all kinds of unexpected results. Depending on your Xcode version it might produces warnings during compile and/or runtime to help identify those scenarios. One pattern to avoid the array changing from under you is to create an immutable copy, like NSArray *immutableT=[t copy]. This produces a shallow copy of the array that is immune to changes to the original mutable array, so you can safely iterate over immutableT.

CodePudding user response:

See The Objective-C Programming Language, Property Declaration Attributes, Atomicity:

If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:

[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

If you specify nonatomic, a synthesized accessor for an object property simply returns the value directly.

  • Related