iOS-SDK只提供了非线程安全的数组。如果要多线程并发的使用一个数组对象就必须要加锁,平凡的加锁使得代码的调用非常的麻烦。

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

1、新建一个对象来对NSMutableArray 数组进行封装,包含dispatch_queue_t 调度队列对象 和一个NSObject 具体操作对象作为成员变量

@interface JXMultiThreadObject : NSObject
{ dispatch_queue_t _dispatchQueue; NSObject *_container;
}
@property (nonatomic, strong) NSObject *container;
@end 

2、再新建JXMutableArray类继承自JXMultiThreadObject并为其声明简单接口来支持其作为Array使用

@protocol JXMutableArrayProtocol
@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 JXMutableArray : JXMultiThreadObject <JXMutableArrayProtocol>
{
} 

并且初始化操作对象

- (id)init
{ self = [super init]; if (self) { self.container = [NSMutableArray array]; } return self;
} 

3、回到JXMultiThreadObject类中 利用下面方法对一个对象无法实现的方法进行拦截和派发

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
} 

该方法当你调用了一个对象没有实现的方法时,forwardInvocation方法将会响应,在这之前需要先实现

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { return [[_container class] instanceMethodSignatureForSelector:aSelector];
} 

才能激活forwardInvocation

4、利用GCD的调度机制对对象和对象的行为进行调度

- (void)forwardInvocation:(NSInvocation *)anInvocation
{ dispatch_barrier_sync(_dispatchQueue, ^{ [anInvocation invokeWithTarget:_container]; });
} 

这里使用了同步的阻塞调度,属于效率比较低的一种调度方式,可以简单地作一下优化

- (void)forwardInvocation:(NSInvocation *)anInvocation
{ NSMethodSignature *sig = [anInvocation valueForKey:@"_signature"]; const char *returnType = sig.methodReturnType; if (!strcmp(returnType, "v")) { dispatch_barrier_async(_dispatchQueue, ^{ [anInvocation invokeWithTarget:_container]; }); } else { dispatch_barrier_sync(_dispatchQueue, ^{ [anInvocation invokeWithTarget:_container]; }); }
} 

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

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

总结:在多线程下使数组安全,就是通过给数组的访问和修改添加同步限制,使数组多线程安全。

同理,字典,集合等多线程安全实现类似。


参考:

http://blog.csdn.net/u010958446/article/details/62227615

http://blog.csdn.net/idaretobe/article/details/22191103

DEMO:https://github.com/joexi/JXMultiThreadObject.git

iOS 多线程安全数组相关推荐

  1. iOS 多线程安全 与可变数组

    完全来自于 iOS 多线程安全与可变字典 的学习 基本相同,举一反三 直接上样例代码 是我参照网上,根据当前业务需求改的. 其实好多人在这里喜欢用类别处理.我个人觉得用类别 极其容易和普通方法混淆,所 ...

  2. iOS多线程:『NSOperation、NSOperationQueue』详尽总结

    2019独角兽企业重金招聘Python工程师标准>>> iOS多线程:『NSOperation.NSOperationQueue』详尽总结 转载: 原地址https://www.ji ...

  3. iOS多线程详解:实践篇

    iOS多线程实践中,常用的就是子线程执行耗时操作,然后回到主线程刷新UI.在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于在iOS中除了主线程,其他子线程是独立 ...

  4. iOS 多线程和GCD(Grand Central Dispath) 教程 (一)

    iOS 多线程和GCD(Grand Central Dispath) 教程 (一)  本文翻译自 Ray Wenderlich 的博客 点击打开原文链接.全部由本人亲手翻译...童叟无欺~ 你有木有遇 ...

  5. iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)

    2017-07-08 remember17 Cocoa开发者社区 目的 本文主要是分享iOS多线程的相关内容,为了更系统的讲解,将分为以下7个方面来展开描述. 多线程的基本概念 线程的状态与生命周期 ...

  6. iOS 多线程的四种技术方案

    iOS 多线程的四种技术方案 image pthread 实现多线程操作 代码实现: void * run(void *param) {for (NSInteger i = 0; i < 100 ...

  7. iOS多线程开发之GCD(基础篇)

    总纲: GCD基本概念 GCD如何实现 GCD如何使用 队列和任务组合 一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的 ...

  8. iOS多线程拾贝------操作巨人编程

    iOS多线程拾贝------操作巨人编程 多线程 基本 实现方案:pthread - NSThread - GCD - NSOperation Pthread 多平台,可移植 c语言,要程序员管理生命 ...

  9. IOS 多线程的一些总结

    IOS 多线程 有三种主要方法 (1)NSThread (2)NSOperation (3)GCD 下面简单介绍这三个方法 1.NSThread 调用方法如下: 如函数需要输入参数,可从object传 ...

最新文章

  1. GCD 容易让人迷惑的几个小问题
  2. 突然就懵了!面试官问我:线程池中多余的线程是如何回收的?
  3. Docker对AUFS的使用
  4. Django项目之小博客
  5. 二十三、Python数据建模(上),禁止转载
  6. think php5是什么,thinkphp5是什么
  7. SpringIOC的依耐注入DI---set注入---constructor有参构造注入---了解P命名空间---了解SpEL
  8. Oracle语句连接查询
  9. Visual C#使用ADO.NET自定义类MyDBase连接SQL Server数据库
  10. 大海中到处是水,海底隧道是怎样修建的?看完真佩服工程师的智慧
  11. python中get属性_python3中__get__,__getattr__,__getattribute__的区别
  12. Linq中字段数据类型转换问题(Linq to entity,LINQ to Entities 不识别方法System.String ToString()问题解决)...
  13. Android studio : 模拟器 真机 运行失败(mac电脑)
  14. 邵阳学院学校云认证码_2021年湖南对口单招升学学校排名
  15. 一个Android健身APP源码(类似KEEP、FEEL、轻+、减约、薄荷等)
  16. 中国地图3D立体效果
  17. 将Ruby和Watir与NUnit集成
  18. 数学|如何求解线性方程系数?
  19. 品牌如何赋能加盟商,攻克时艰
  20. synplify user guide note1

热门文章

  1. MySQL 创建表 CREATE TABLE 语法
  2. 因为相信所以看见,既然看见注定坚信《13》
  3. 全国计算机等级考试-数据库四级备考资料
  4. 企业微信点餐系统读后感
  5. 手机屏幕投影到投影仪_投影机与大屏幕电视:您应该购买哪一个?
  6. android应用换字体,Android手机字体随意换-字体管家
  7. php教师试讲,教师面试试讲禁忌
  8. 内容安全策略(CSP)
  9. 【Java】继承法——猫狗动物类
  10. PTA - 简单计算器