On Jun 22, 2011, at 1:49 PM, Ken Tozier wrote:

> For those of us new to @synthesize, would it be possible to get concrete 
> examples of exactly what it does to create "thread safety? What is Apple 
> doing, under the hood, to provide this?

Well, obviously, that's an implementation detail.  Any explanation has to be 
caveated out the wazoo that we don't really know and, if we did, it could 
change at any time.  Consider yourself caveated.


> For example: Say I have 3 properties, a float, a struct and an NSObject 
> subclass. Written by hand they might look like
> 
> - (void) setScalar:(float) inValue
> {
>       floatProp               = inValue;
> }
>> 

> - (void) setObject(id) inValue
> {
>       objectProp              = inValue;
> }

For the above two, if you're using managed memory and the object property is 
merely "assign", nothing would be necessary on any likely CPU architecture.  
(I'm not really familiar with ARM, but I'd be surprised if the above weren't 
atomic.)  If you're using GC, what's apparently a simple assignment in the 
object case isn't any longer.  The compiler emits a write barrier.  I'm not 
sure what the atomicity implications of that are.

> - (void) setStruct:(MyStruct) inValue
> {
>       structProp              = inValue;
> }

The issue here is that two threads might simultaneous be running -setStruct:.  
Or, one thread might be running -struct (the getter) while -setStruct: is 
running in another.  Assuming a non-trivial struct, the CPU will be using 
multiple instructions to copy the fields of the struct.  The threads can be 
interrupted at any point.  So, a getter might get half of the old struct and 
half the new.  Or the two setters could overwrite each other -- the first 
thread writes part of the struct and is interrupted, the second thread writes 
over the entire struct, the first thread resumes and finishes writing what it 
didn't get to previously.  So, the instance variable contains a mishmash of 
values, some from the first thread's copy and some from the second thread's.

The above explanation is somewhat simplified.  There can be more than two 
threads.  Both the compiler and the CPU can do wholly non-intuitive things to 
your code and its effects.  Etc.


> If for some reason, we have to write accessors for some properties, what 
> might those three look like if we could look into the source of properties 
> created by synthesize? 

You would want the getter and the setter to use a shared lock to make sure that 
only one is running at a time and to counteract some of the non-intuitive stuff 
done by the compiler and CPU.

For example:

- (MyStruct)struct
{
        @synchronized(self) {
                return structProp;
        }
}

- (void) setStruct:(MyStruct)inValue
{
        @synchronized(self) {
                structProp = inValue;
        }
}

Now, @synchronized is fairly expensive.  You could use NSLock for some speed 
improvement.  Apparently, synthesized accessors use an even more efficient lock.

Also, I have synchronized on the object (self).  If the other atomic properties 
use the same mechanism, then they are all synchronized with each other, which 
is not strictly necessary for the atomicity of each property in isolation.  
That means there will be more contention around that shared lock than is 
necessary, which is also inefficient.  If you use NSLock, you could use a 
separate lock object for each atomic property, which is more efficient.  And, 
again, synthesized accessors do something like that.

All of that said, keep in mind Apple's advice that atomic properties are _not_ 
sufficient for general thread safety.  They only protect against a certain 
narrow thread safety issue.  There are many others, which almost always require 
synchronization mechanisms at a high level of the design of your classes.

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to