iOS中有一些类在多线程下操作是不安全的,比如我们常使用的可变类型:NSMutableArray,NSMutableDictnory,NSMutableString...,我们可以通过CGD对这些类进行构建,使这些类在多线程下的操作达到安全的目的。
使用同步串行队列构建
@interface LockArray : NSObject
@property (nonatomic,readonly,assign) NSUInteger count;
- (id)objectAtIndex:(NSUInteger)index;
- (NSEnumerator *)objectEnumerator;
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
- (NSUInteger)indexOfObject:(id)anObject;
@end
#import "LockArray.h"
@interface LockArray ()
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) dispatch_queue_t dispatchQueue;
@end
@implementation LockArray
- (instancetype)init{
if (self) {
NSString* queueid = [NSString stringWithFormat:@"com.lock.array_%p", self];
_dispatchQueue = dispatch_queue_create([queueid UTF8String], DISPATCH_QUEUE_SERIAL);
_array = [NSMutableArray array];
}
return self;
}
-(NSUInteger)count
{
__block NSUInteger count;
dispatch_sync(_dispatchQueue, ^{
count = _array.count;
});
return count;
}
- (id)objectAtIndex:(NSUInteger)index{
__block id obj;
dispatch_sync(_dispatchQueue, ^{
if (index < [_array count]) {
obj = _array[index];
}
});
return obj;
}
- (NSEnumerator *)objectEnumerator{
__block NSEnumerator *enu;
dispatch_sync(_dispatchQueue, ^{
enu = [_array objectEnumerator];
});
return enu;
}
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index{
dispatch_sync(_dispatchQueue, ^{
if (anObject && index < [_array count]) {
[_array insertObject:anObject atIndex:index];
}
});
}
- (void)addObject:(id)anObject{
dispatch_sync(_dispatchQueue, ^{
if(anObject){
[_array addObject:anObject];
}
});
}
- (void)removeObjectAtIndex:(NSUInteger)index{
dispatch_sync(_dispatchQueue, ^{
if (index < [_array count]) {
[_array removeObjectAtIndex:index];
}
});
}
- (void)removeLastObject{
dispatch_sync(_dispatchQueue, ^{
[_array removeLastObject];
});
}
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
dispatch_sync(_dispatchQueue, ^{
if (anObject && index < [_array count]) {
[_array replaceObjectAtIndex:index withObject:anObject];
}
});
}
- (NSUInteger)indexOfObject:(id)anObject{
__block NSUInteger index = NSNotFound;
dispatch_sync(_dispatchQueue, ^{
for (int i = 0; i < [_array count]; i ++) {
if ([_array objectAtIndex:i] == anObject) {
index = i;
break;
}
}
});
return index;
}
- (void)dealloc{
if (_dispatchQueue) {
_dispatchQueue = NULL;
}
}
@end
同步串行队列虽然可以达到线程安全的目的,但效率没那么高,如果能将同步与异步派发结合起来,实现与普通加锁机制一样的同步行为,又不会阻塞执行异步派发的线程,效率会比单纯的同步要好
并发队列结合栅栏块
当我们进行读的操作时使用同步执行,当进行写的操作时使用异步栅栏
@interface HLockArray : NSObject
@property (nonatomic,readonly,assign) NSUInteger count;
- (id)objectAtIndex:(NSUInteger)index;
- (NSEnumerator *)objectEnumerator;
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
- (NSUInteger)indexOfObject:(id)anObject;
@end
@interface HLockArray ()
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) dispatch_queue_t dispatchQueue;
@end
@implementation HLockArray
- (instancetype)init{
if (self) {
NSString* queueid = [NSString stringWithFormat:@"com.lock.array_%p", self];
_dispatchQueue = dispatch_queue_create([queueid UTF8String], DISPATCH_QUEUE_SERIAL);
_array = [NSMutableArray array];
}
return self;
}
- (NSUInteger)count{
__block NSUInteger count;
dispatch_sync(_dispatchQueue, ^{
count = _array.count;
});
return count;
}
- (id)objectAtIndex:(NSUInteger)index{
__block id obj;
dispatch_sync(_dispatchQueue, ^{
if (index < [_array count]) {
obj = _array[index];
}
});
return obj;
}
- (NSEnumerator *)objectEnumerator{
__block NSEnumerator *enu;
dispatch_sync(_dispatchQueue, ^{
enu = [_array objectEnumerator];
});
return enu;
}
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index{
dispatch_barrier_async(_dispatchQueue, ^{
if (anObject && index < [_array count]) {
[_array insertObject:anObject atIndex:index];
}
});
}
- (void)addObject:(id)anObject{
dispatch_barrier_async(_dispatchQueue, ^{
if(anObject){
[_array addObject:anObject];
}
});
}
- (void)removeObjectAtIndex:(NSUInteger)index{
dispatch_barrier_async(_dispatchQueue, ^{
if (index < [_array count]) {
[_array removeObjectAtIndex:index];
}
});
}
- (void)removeLastObject{
dispatch_barrier_async(_dispatchQueue, ^{
[_array removeLastObject];
});
}
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
dispatch_barrier_async(_dispatchQueue, ^{
if (anObject && index < [_array count]) {
[_array replaceObjectAtIndex:index withObject:anObject];
}
});
}
- (NSUInteger)indexOfObject:(id)anObject{
__block NSUInteger index = NSNotFound;
dispatch_sync(_dispatchQueue, ^{
for (int i = 0; i < [_array count]; i ++) {
if ([_array objectAtIndex:i] == anObject) {
index = i;
break;
}
}
});
return index;
}
- (void)dealloc{
if (_dispatchQueue) {
_dispatchQueue = NULL;
}
}
参考文章:
Cocoa线程安全/非线程安全的类和函数汇总
大牛们是如何构建一个线程安全的字典的!
关于NSMutableArray线程安全的思考和实现
网友评论