Twilite
Twilite

Reputation: 873

Avoid getting released objects from concurrently used accessors

In my multithreaded application, there is a property that can be accessed concurrently by multiple threads. The property is defined as @property (retain) NSObject *status.

How do I atomically get and retain the property, so I can safely use it in my local scope? What is the best practice to store and retrieve such a value?

NSObject *status = [self status];
[... do some processing on status ...]

// But: I cannot rely on the object assigned to my status variable 
// still being valid, since another thread might have used my 
// [self setStatus] accessor, implicitly calling a release on the old object, 
// releasing it under my feet.
// Not even NSObject *status = [[self status] retain]; would fix that.

Upvotes: 2

Views: 153

Answers (1)

justin
justin

Reputation: 104698

In my multithreaded application, there is a property that can be accessed concurrently by multiple threads. The property is defined as @property (retain) NSObject *status.

atomic is the default - there is no keyword or specifier required.

How do I atomically get and retain the property, so I can safely use it in my local scope?

Since it's atomic, retained, readwrite and @synthesized, you can just always use the accessors. Provided you access the ivar directly in your initializers and dealloc only -- and use the accessors everywhere else, it will be safe in the regard which you're asking about. The return value is retain+autoreleased. Since it's autoreleased, the object will live on -- at least until the top autorelease pool on the local thread is popped.

The last time I stepped through, it looked something like this (in simple form):

- (NSObject *)object
{
    enter_object_level_spin_lock();
    id ret = [[object retain] autorelease];
    exit_object_level_spin_lock();
    return ret;
}

although i don't remember if the autorelease was in the lock or not (it would ideally be outside for shorter lock times).

What is the best practice to store and retrieve such a value?

Atomic properties do very little for concurrency or thread safety -- don't consider them a substitute for proper thread safety. It's also unusual for thread safety to be covered by what atomic property accessors provide. Typically, you will need more than an atomic for a proper concurrent program. I very very rarely use atomic properties, and make some crazy concurrent programs. If you need high performance/transaction concurrency, you will need to know how to use locks effectively. Of course, there are many ways to avoid concurrent designs as well. My automatic solution involves handling locking myself.

Upvotes: 4

Related Questions