Recently, I suddenly want to review the thread-safety problem of variable arrays, and I just looked at the implementation of YYKit before, is to control the implementation of semaphores. But the semaphore value is 1, which is thread-safe but limits the condition for multiple reads. So I turned over some methods recently realized on the Internet to update my previous cognition.

At present, most of the online implementation methods are through dispatch_barrier_async to implement single write. Through parallel + synchronization to achieve multi-read.

Create a mutable array of objects. Create a mutable array of objects.

  • Create a parallel thread to allocate degree operations.
#import "SafeMutableArr.h" @interface SafeMutableArr () /** * */ @property (nonatomic, strong) dispatch_queue_t ayncQueue; /** * */ @property (nonatomic, strong) NSMutableArray *array; @end @implementation SafeMutableArr - (instancetype)initCommon { self = [super init]; if (self) { NSString *uuid = [NSString stringWithFormat:@"com.shuxia.array_%p",self]; _ayncQueue = dispatch_queue_create([uuid UTF8String], DISPATCH_QUEUE_CONCURRENT); } return self; } - (instancetype)init { self = [self initCommon]; if (self) { _array = [NSMutableArray array]; } return self; } #pragma mark -- array -(NSMutableArray *)safeArray{__block NSMutableArray *safeArra; dispatch_sync(_ayncQueue, ^{ safeArra = _array; }); return safeArra; }Copy the code

Anything that involves modifying an array element uses the fence function to restrict synchronous execution. All the read operations involved are distributed with synchronous + parallel. Let me give you two quick examples

  • Insert elements into an array:
- (void)insertObject:(id)anObject atIndext:(NSUInteger) index{ dispatch_barrier_async(_ayncQueue, ^{ if (anObject && index < [self->_array count]) { [self->_array insertObject:anObject atIndex:index]; }}); }Copy the code
  • Query the number of arrays
#pragma mark -- contains an element or not -- (BOOL)containObject:(id)anObject{__block BOOL isExist; dispatch_sync(_ayncQueue, ^{ isExist = [_array containsObject:anObject]; }); return isExist; }Copy the code