美文网首页
iOS EXC_BAD_INSTRUCTION类型 奔溃

iOS EXC_BAD_INSTRUCTION类型 奔溃

作者: 路飞_Luck | 来源:发表于2018-07-12 09:56 被阅读105次
序言

在做项目的时候,遇到一个巨坑,在使用dispatch_group 的时候遇到奔溃,此问题较难定位,但是解决方法较为简单,详细如下所示。

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

问题核心:

对dispatch_group 进行了额外的 leave 操作

问题代码

- (void)errorRequest {
    dispatch_group_t group = dispatch_group_create();
    self.group = group;
    
    // enter code
    [request  requestGetUrl:url success:^(id responds) {
        // leave code
    }];
}

修正后代码

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

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

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

image.png
1. 正常情况下:执行步骤1的问题间隔时间充分长,或者只执行一次,此逻辑没有问题,不会 crash。
2. 非正常情况下:开头所说的 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 进行地址引用。

模拟网络请求奔溃代码
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_group_t group = dispatch_group_create();
    self.group = group;
    
    dispatch_group_enter(self.group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });
    
    dispatch_group_enter(self.group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });

    dispatch_group_enter(self.group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });

    dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
        NSLog(@"操作全部完成");
    });
}

多次点击屏幕后发生crash

image.png
修正后网络请求代码
- (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_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });
    
    dispatch_group_enter(self.group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });

    dispatch_group_enter(self.group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        dispatch_group_leave(self.group);
    });

    dispatch_group_notify(self.group, dispatch_get_main_queue(), ^{
        NSLog(@"操作全部完成");
    });
}

运行结果

image.png

没有发生奔溃


本文参考iOS开发--Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 的一类解决办法,非常感谢该作者。

iOS疑难问题排查之深入探究dispatch_group crash,这篇博客介绍的非常详细,有深度。


项目连接地址

相关文章

  • iOS EXC_BAD_INSTRUCTION类型 奔溃

    序言 在做项目的时候,遇到一个巨坑,在使用dispatch_group 的时候遇到奔溃,此问题较难定位,但是解决方...

  • iOS奔溃日志分析

    iOS奔溃日志分析 前言(扯淡) iOS奔溃日志能够比较有效的分析奔溃的原因,方便我们debug我们的项目。当然现...

  • DYLD, Library not loaded: /usr/l

    奔溃日志 奔溃表现:iOS12.1 及以下启动奔溃奔溃日志: 解决方法:关闭bitcode,重新打包上传appst...

  • iOS-千奇百怪的奔溃

    App 上线后,我们最怕的应该就是异常奔溃了。常见的奔溃类型分两种:信号可捕获奔溃、信号不可捕获奔溃,前者比较典型...

  • iOS13 textfield的placeholder字体颜色崩

    由于iOS13禁止了textfield通过KVC获取私有属性,出现奔溃问题 奔溃报错Access to UITex...

  • iOS奔溃信息类型捕捉与分析

    iOS 异常奔溃类型分类 1.数组越界导致的崩溃 2.数据集合类型,如字典、数组中插入元素时,插入空指针nil 3...

  • iOS崩溃类型

    奔溃类型:·Mach kernel exceptions //内核异常· Fatal signals //信号 ...

  • iOS Crash(崩溃)类型

    废话不多说,直接看iOS APP奔溃的几种类型 1.Mach异常 Mach 是一个 XNU 的微内核核心,Mach...

  • iOS收集Crash信息上报

    在iOS开发中,最严重的bug估计就是应用奔溃,如果应用奔溃了,除了做好挨骂的准备,还需要冷静的下来去处理这个事情...

  • iOS之奔溃记录

    实在是不知道该写点什么,就写下如何记录程序的Crash吧。 原理很简单,就是创建一个Crash的管理对象,然后记录...

网友评论

      本文标题:iOS EXC_BAD_INSTRUCTION类型 奔溃

      本文链接:https://www.haomeiwen.com/subject/dhklpftx.html