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