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

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

 

 

 

 

©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页