iOS 如何创建一个线程安全的数组

news/2024/7/20 20:23:23 标签: ios, 安全性测试, objective-c

背景

我们平时使用的NSMutableArray,在进行增删改查的时候,会出现数据异常的场景(关键是异常并不是必现的,不太好复现)

尝试复现场景

先执行以下代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

self.muArray = [NSMutableArray new];

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        [self.muArray addObject:@(i)];

        NSLog(@"====[%d]", (int)self.muArray.count);

    }

});

     

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        [self.muArray addObject:@(10000+i)];

        NSLog(@"====[%d]", (int)self.muArray.count);

    }

});

运行代码,发现最后array的个数并不等于6000,多运行几次,发现每次的结果都不一样

创建线程安全的数组

1、通过NSLock锁实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

NSLock *lock = [NSLock new];    

self.muArray = [NSMutableArray new];

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        [lock lock];

        [self.muArray addObject:@(i)];

        NSLog(@"====[%d]", (int)self.muArray.count);

        [lock unlock];        

    }

});

     

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        [lock lock];

        [self.muArray addObject:@(i)];

        NSLog(@"====[%d]", (int)self.muArray.count);

        [lock unlock];

    }

});

2、通过串行队列实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

dispatch_queue_t serialQueue = dispatch_queue_create("com.name.apple", DISPATCH_QUEUE_SERIAL);  

self.muArray = [NSMutableArray new];

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        dispatch_async(serialQueue, ^{

            [self.muArray addObject:@(i)];

            NSLog(@"====[%d]", (int)self.muArray.count);             

        });

    }

});

     

dispatch_async(dispatch_get_global_queue(00), ^{

    for (int i = 0; i < 3000; i++) {

        dispatch_async(serialQueue, ^{

            [self.muArray addObject:@(i)];

            NSLog(@"====[%d]", (int)self.muArray.count);

        });

    }

});


http://www.niftyadmin.cn/n/789378.html

相关文章

让Outlook一直保持开启

1.将OutLook.exe注册为服务&#xff0c;让其一直保持开启状态 类似于TaobaoProtect.exe是由TBSecSvc服务启动的 http://stackoverflow.com/questions/3582108/create-windows-service-from-executable# You can use sc.exe (required when using Powershell): sc create <ne…

请注意程序中的\r和\n字符

这几天&#xff0c;由于项目要求&#xff0c;需要写一个从数据库批量读取数据然后写入HDFS的一个程序&#xff0c;本来算不上什么比较难的问题&#xff0c;但程序运行完后&#xff0c;发现在程序log里记录的数据总量&#xff0c;与实际的写入到文件里的总数不一致&#xff0c;然…

cuda向量加法时间

#include<stdio.h> #include<stdlib.h> #include<cuda_runtime.h> #include<sdkHelper.h> void output(float *arr,int n);//输出向量中的元素值 void VectorAdd(float *A,float *B,float *C,int n);//CPU上计算两向量相加 //device code __global__ v…

浅谈WCF的三种通信模式:请求响应模式、数据报模式和双工通讯模式

一: WCF的服务端与客户端在通信时有三种模式&#xff1a;请求响应模式、数据报模式和双工通讯模式。 说一下基本知识, 1、如果想要将当前接口作为wcf服务器&#xff0c;则一定要加上[ServiceContract] 契约 2、要想将方法作为wcf服务方法发布给外部调用&#xff0c;则一定要加上…

MySQL语句(DQL篇(二))

DQL篇&#xff08;二&#xff09;前言一、DQL&#xff1a;查询语句示例&#xff1a;1.排序查询2.聚合函数&#xff1a;3.分组查询4.分页查询&#xff1a;总结前言 上篇的DQL&#xff08;一&#xff09;没有总结DQL查询语句的具体使用&#xff0c;这篇来补上剩余的笔记&#xf…

CAS原子操作实现无锁及性能分析

Author&#xff1a;Echo Chen&#xff08;陈斌&#xff09; Email&#xff1a;chenb19870707gmail.com Blog&#xff1a;Blog.csdn.net/chen19870707 Date&#xff1a;Nov 13th, 2014 最近在研究nginx的自旋锁的时候&#xff0c;又见到了GCC CAS原子操作&#xff0c;于是…

CentOS构造SNMP

<span style"font-size:14px;">本文介绍怎样在CentOS环境下配置一个简单的SNMP服务</span>软件安装 切换到系统管理员帐户 安装snmp 确认snmp代理已安装 rpm -q net-snmp 假设未安装。安装snmp yum install net-snmp 设置开机自己主动执行snmp /sbin/ch…

MySQL语句(DQL篇(三))

DQL篇&#xff08;三&#xff09;前言一、多表查询的条件1、查询语句2、笛卡尔积二、多表查询的分类1.内连接查询1、隐式内连接2、显式内连接2.外连接查询&#xff1a;1、左外连接2、右外连接子查询1、概念2、子查询的不同情况1、子查询的结果是单行单列的2、子查询的结果是多行…