浅谈一种规避iOS多线程Crash的方案

本文探讨了iOS多线程编程中常见的Crash场景,特别是涉及到可变数组和字典的读写操作。文章列举了多种避免Crash的解决方案,包括@property的atomic属性、@synchronized、NSLock和GCD,并对比了它们的性能和适用性。最后提出了保证同一数组/字典操作顺序执行的最终方案,以确保多线程环境下的安全性。
摘要由CSDN通过智能技术生成

一般来说,多线程编程因具有以下几个优点,一直被广泛应用:

  • 资源利用率更好
  • 程序设计在某些情况下更简单
  • 程序响应更快

但是因为多线程而导致的crash问题,也是令程序员非常头疼的一个问题,因为线程调度执行顺序的不确定性,造成了crash一般都是小概率出现,在开发测试阶段很难发现,而一旦上线面对用户,造成的影响却是不容小觑的。

一、Crash的场景

有一种特别常见的会造成crash的场景为:多线程读写可变数组/字典

我们来看几个简单的测试代码,看看到底在什么情况下会引起Crash:

// 1. 多线程只读数据
NSMutableDictionary * dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:@"test0" forKey:@"test0"];
[dict1 setObject:@"test1" forKey:@"test1"];
[dict1 setObject:@"test2" forKey:@"test2"];
for (int i = 0; i < 1000; i++) {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSString * key = [NSString stringWithFormat:@"test%d", i%3];
        NSString * value = dict1[key];
        NSLog(@"%@:%@", key, value);
    });
}
    
// 2. 多线程只写数据
// 字典仅有一个key
// 多线程写同一个key
NSMutableDictionary * dict2 = [[NSMutableDictionary alloc] init];
for (int i = 0; i < 1000; i++) {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [dict2 setObject:@(i) forKey:@"test"];
    });
}

// 3. 多线程只写数据
// 字典有多个key
// 多线程同时写不同key
NSMutableDictionary * dict3 = [[NSMutableDictionary alloc] init];
for (int i = 0; i < 1000; i++) {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [dict3 setObject:[NSString stringWithFormat:@"test%d", i] forKey:[NSString stringWithFormat:@"test%d", i]];
    });
}

// 4. 多线程只写数据
// 字典有多个key
// 多线程随机写key
NSMutableDictionary * dict4 = [[NSMutableDictionary alloc] init];
for (int i = 0; i < 1000; i++) {
    int x = arc4random() % 3;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [dict4 setObject:[NSString stringWithFormat:@"test%d", i] forKey:[NSString stringWithFo
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值