Reputation: 811
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
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
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