Smart Home
Smart Home

Reputation: 811

How to make a custom class thread-safe in Objective-C

I've a TableViewController that uses the item at index N for the table view cell at row N. Since array index N may be accessed from different threads, I created a ThreadSafeMutableArray class that does the reads inside a dispatch_sync and writes under a dispatch_barrier_async.

Suppose I get the object at index N, say using Song *currSong = self.entries[N];, and then make changes to the properties of this object. Am I correct in understanding that I need to make these changes in a thread-safe way (because for e.g, tableview may ask for the object at cell N and at the same time the object in cell N may be updated because the image object for which it was received from the network)? If yes, what is the simplest way to make my custom class thread-safe?

For example : In the ThreadSafeMutableArray case, I was able to achieve it by over-riding following methods and using dispatch_sync and dispatch_barrier_async within the new implementation of the methods.

-(NSUInteger) count
-(id) objectAtIndex:(NSUInteger)index;
-(void) insertObject:(id)anObject atIndex:(NSUInteger)index;
-(void) removeObjectAtIndex:(NSUInteger)index;
-(void) addObject:(id)anObject;
-(void) removeLastObject;
-(void) replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;

Upvotes: 1

Views: 668

Answers (2)

CRD
CRD

Reputation: 53000

You need to determine what "thread safe" means in the context of your custom class/application. You might just want data integrity, meaning that no thread sees an invalid or partial stored value, e.g. Think of atomic read/write operations; or you might required model integrity, e.g. where the interrelationships of multiple items is always correct - as in your mutable array; or something between these, e.g. think of counter incrementing - it is not as involved as keeping the graph of objects representing a mutable structure consistent, but more involved than simple atomic read or write. Etc., etc., thread safety is a big topic!

Once you know what your custom object requires you can select from atomic properties for simple read/write integrity, locks for more complex combinations, combinations of GCD sync, async, barrier, sequential and concurrent queues etc.

In short there is no single simple answer. Study the various options, consider your requirements, and pick and choose. You are already using GCD to achieve thread safety, that is good! If you come up with a design and have issues with it you can always ask SO.

You might find this article interesting on the benefits, or otherwise, of atomic properties. The writer is probably being a bit harsh on atomic to make a point, but it is certainly worth a read.

HTH

Upvotes: 1

Thomm
Thomm

Reputation: 516

The easiest way to achieve this is to create a singel access mehtod in your TableViewController and use the @syncrhonized directive to protect access.

    - (void)updateObjectAt:(NSUInteger)index {
        @synchronized(itemArray) {
            // Everything between the braces is protected by the @synchronized directive.
            itemArray[index].update();
        }
    }

The @synchornized directive puts a lock on the array, anything within the code block can safely access and change items in the array. If any other methods need to access the array simply wrap it in a @syncrhonized lock on the array aswell.

Upvotes: 0

Related Questions