iOS 多线程安全的数组MultiThreadSafeObject

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

@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指定不同的调度规则以确保在逻辑正常的情况下拥有最高的性能。

代码

你可能感兴趣的:(iOS 多线程安全的数组MultiThreadSafeObject)