您的位置:首页 > 移动开发 > Objective-C

iOS 多线程安全的数组MultiThreadSafeObject

2017-12-19 14:00 375 查看
iOS只提供了非线程安全的数组。

如果要多线程并发的使用一个数组对象就必须要加锁,频繁加锁使代码的调用非常的麻烦。

我们需要多线程的读写锁在类的内部实现,所以需要对NSMutableArray进行封装,封装后的对象负责接受所有事件并将其转发给真正的NSMutableArray对象,并通过合理的调度使得其支持多线程并发。

新建一个对象来对NSMutableArray 数组进行封装,包含

dispatch_queue_t 调度队列对象 和一个

NSObject 具体操作对象作为成员变量

@implementation MultiThreadSafeObject
- (id)init
{
self = [super init];
if (self)
{
_mtsDispatchQueue = dispatch_queue_create("COM.MTS.MultiThreadSafeObject", NULL);
}
return self;
}

- (void)dealloc
{
_mtsDispatchQueue = nil;
_mtsContainer = nil;
}


我们再新建mtsMutableArray类继承自MultiThreadSafeObject并为其声明简单接口来支持其作为Array使用

#import "MultiThreadSafeObject.h"

@protocol mtsMutableArrayProtocol

@optional
- (id)lastObject;
- (id)objectAtIndex:(NSUInteger)index;
- (NSUInteger)count;

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

@end

@interface mtsMutableArray : MultiThreadSafeObject<mtsMutableArrayProtocol>

@end


使用消息转发

#pragma mark - public method
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [[_mtsContainer class] instanceMethodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
NSMethodSignature *sig = [anInvocation valueForKey:@"_signature"];

const char *returnType = sig.methodReturnType;
//NSLog(@"%@ = > %@",anInvocation.target, NSStringFromSelector(anInvocation.selector));
//NSLog(@"%s",returnType);

if (!strcmp(returnType, "v"))
{
//没有返回值 setter方法 异步barrier
/** the setter method just use async dispatch
remove the barrier to make it faster when u r sure that invacations will not affect each other
*/
dispatch_barrier_async(_mtsDispatchQueue, ^{
[anInvocation invokeWithTarget:_mtsContainer];
});
}
else
{
//有返回值 getter方法 同步barrier
/** all getter method need sync dispatch
barrier make sure the result is correct
getter method need barrier in most ways unless u dont except this */

dispatch_barrier_sync(_mtsDispatchQueue, ^{
[anInvocation invokeWithTarget:_mtsContainer];
});
}
}


获取调度方法的返回值,如果是void型方法则使用异步调度,如果是getter类型的则使用同步调度,可以略微的提升性能。

可以通过继承等方法为不同类型的container指定不同的调度规则以确保在逻辑正常的情况下拥有最高的性能。

代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: