iOS-@synchronized(self) 线程锁引起的Crash问题

本文分析了一个在友盟上排名首位的Bug——ApplicationreceivedsignalSIGABRT(null),并详细探讨了其原因在于线程安全处理不当导致的程序效率低下和潜在的系统杀死风险。通过将@synchronized互斥锁替换为串行队列,有效解决了同步锁带来的阻塞问题,提高了程序响应速度。

Application received signal SIGABRT (null)

错误说明

熟悉公司的项目,在友盟上排第一的有个Bug,看了一下,错误的标题是“Application received signal SIGABRT (null)”,具体错误细节如下:

错误分析

定位到具体代码如下:

@synchronized (self) {
        dispatch_async(dispatch_get_main_queue(), ^{
            @try {
                if ([self.dao insertOrModify:model] == 1) {
                    if ([[self.cache allKeys]containsObject:traceId]) {
                        [self.cache removeObjectForKey:traceId];
                        [[UrielCache sharedUrielCache] removeDataByTraceId:traceId];
                        [[UrielCache sharedUrielCache] removeNumByTraceId:traceId type:CacheDataTypeDownload];
                        EELog(@"%@", [model toDictionary]);
                    }
                }
            } @catch (NSException *exception) {
                NSLog(@"插入错误");
            }
        });
    }

从上面的代码可以看出,该兄弟是为了线程安全使用了@synchronized的互斥锁,以保证此时没有其它线程对self对象进行修改!但是这样写会使程序的处理效率变低,这样会有一个线程阻塞的情况,因为其他消息过来都要等待,如果有任务耗时过长,那么就会长时间无响应,也就会被系统杀死掉!

解决办法

我们可以考试使用线程队列来做,避免同步锁的出现!!!

注意:需要特别说明的是,我这里使用的线程队列是主线程的同步队列,大家可以根据具体需求修改自己的线程逻辑!

修改如下:

- (dispatch_queue_t)serialQueue{
    if(_serialQueue == nil){
        _serialQueue = dispatch_queue_create("zfjQu", DISPATCH_QUEUE_CONCURRENT);
    }
    return _serialQueue;
}
dispatch_sync(self.serialQueue, ^{
        @try {
            if ([self.dao insertOrModify:model] == 1) {
                if ([[self.cache allKeys]containsObject:traceId]) {
                    [self.cache removeObjectForKey:traceId];
                    [[UrielCache sharedUrielCache] removeDataByTraceId:traceId];
                    [[UrielCache sharedUrielCache] removeNumByTraceId:traceId type:CacheDataTypeDownload];
                    EELog(@"%@", [model toDictionary]);
                }
            }
        } @catch (NSException *exception) {
            NSLog(@"插入错误");
        }
    });

结束语

欢迎各位过往大佬提供宝贵的建议和意见,欢迎大家进群交流3 6 5 1 5 2 0 4 8

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值