iOS开发--Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 的一类解决办法

崩溃的截图:


image.png
image.png

最近项目中有一个dispatch_group相关的巨坑(此问题解决方法很简单,难点是定位问题),特此记录下来并分享,希望帮助到有需要的人!

本文涉及的知识面较广,有一定的逻辑性,如果想真正明白各种原理,请细细读来,如时间紧迫,可记住正确使用方法亦可!

阅读本文需要的知识点:

 1 熟悉AFNetworking
 2 熟练使用dispatch_group
 3 了解接口的含义
 4 熟悉block工作原理
 5 熟悉地址引用含义

先把crash场景和解决方案放在开头:

crash场景:

1 有一组多个接口地址
2 利用  dispatch_group并发请求到数据后,统一回调(必要:利用AF进行网络请求)
3 频繁调用2(必要)
4 每次调用2中的请求是同一组接口地址(必要)
注:频繁的意思是一秒调用3次或3次以上

问题核心:

对dispatch_group进行了额外的leave操作

问题代码:

-(void)request{
    dispatch_group_t group = dispatch_group_create();
    self.group = group;

   enter代码....
  [request  requestGetUrl:url success:^(id responds) {
    leave代码....
  }];     
} 

修正后代码:

-(void)request{
  if(self.group == nil){
    dispatch_group_t group = dispatch_group_create();
    self.group = group;
  }
   enter代码....
  [request  requestGetUrl:url success:^(id responds) {
    leave代码....
  }];     
} 

我想你肯定在疑惑加一个if判断就解决了问题了,那这个坑应该不大,分分钟搞定,请往下看

产生此问题的原因:概括的说是dispatch_group的原理和AFNetworking网络请求回调block的缓存回调原理的协作问题

举例详细说明,流程图如下:


image.png
正常情况下:执行步骤1 的间隔时间充分长,或者只执行一次,此逻辑没有问题,不会crash;
非正常情况:开头所说的crash出现场景下,即频繁执行上图中步骤1到步骤3

因为网络请求的耗时和异步特性,这时候会发生一种情况

1 第一次在步骤1创建了一个新的group1,这时网络请求n1到n4请求未返回,也就是b1到b4
   还未调用;
2 此时又执行了一次步骤一创建了一个新的group,命名为group2(这是一个新的,代码见上图),
  并且赋值给了self.group,又执行步骤二,对group2进行enter,发送网络请求;
3 此时若是1中的网络请求返回了,b1到b4就会调用,会对步骤2中创建的新的group2进行
  leave操作,当2中的网络请求返回,进行回调时,会发生对group2进行额外的leave操作,
  从而造成crash;
注:b1到b4因为leave的需要,会对group进行地址引用

作者受此文启发,虽场景不同,但原理一致!


---2018-03-14更新错误代码实例 --start
附1:
错误代码实例(崩溃截图见代码下边):

 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
dispatch_group_t group = dispatch_group_create();
self.group = group;
dispatch_group_enter(self.group);
dispatch_group_enter(self.group);
dispatch_group_enter(self.group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    dispatch_group_leave(self.group);
    sleep(2);
    dispatch_group_leave(self.group);
     dispatch_group_leave(self.group);
});
dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
    NSLog(@"1234567");
});   
}
崩溃截图

修正后代码:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if(self.group == nil){
    dispatch_group_t group = dispatch_group_create();
    self.group = group;
}
dispatch_group_enter(self.group);
dispatch_group_enter(self.group);
dispatch_group_enter(self.group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    dispatch_group_leave(self.group);
    sleep(2);
    dispatch_group_leave(self.group);
    dispatch_group_leave(self.group);
});

dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
    NSLog(@"1234567");
});    
}

---2018-03-14更新错误代码实例 --end


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • iOS中GCD的使用小结 作者dullgrass 2015.11.20 09:41*字数 4996阅读 20199...
    DanDanC阅读 810评论 0 0
  • 目录: (一)线程与进程之间的区别 (二)为什么需要学习多线程 (三)多线程任务执行方式 (四)多线程执行的...
    KingLionsFrank阅读 771评论 6 6
  • Managing Units of Work(管理工作单位) 调度块允许您直接配置队列中各个工作单元的属性。它们还...
    edison0428阅读 7,931评论 0 1
  • 最全的iOS面试题及答案 iOS面试小贴士 ———————————————回答好下面的足够了-----------...
    大罗Rnthking阅读 959评论 0 2
  • 我们习惯了花2元钱买一瓶矿泉水,30元买一杯咖啡,400元买一件Zara, 5000元买一部手机,上万元完成一次旅...
    喵咪英语世界阅读 1,006评论 5 11