DispatchGroup出现EXC_BAD_INSTRUCTION问题

前言

前段时间看app的线上奔溃总是出现意义不明的崩溃问题,而且崩溃栈出现在闭包的回调里,并且bugly上提示说是有可能在swift解包的时候出现问题,也就是对nil使用了!。这就完全误导了我,把我对问题的理解定义为数据保护的不够到位。结果就是在多次发版后这个问题还未得到解决,所以我绝对对这个问题一探究竟。

出现问题的原因

其实出现这个问题的原因很简单,那就是group的enter和leave没有成对出现。比如说我们会在闭包的回调里去leave,但是闭包有可能返回多次,一旦多leave了,那么就会出现EXC_BAD_INSTRUCTION这个问题。

举个例子

我们声明如下两个方法,可以看出来work2回调了两次

    func work1(closure: () -> Void) {
        sleep(1)
        closure()
    }
    
    func work2(closure: () -> Void) {
        closure()
        sleep(2)
        closure()
    }

接着我们使用它们

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let group = DispatchGroup()
        let queue = DispatchQueue(label: "test", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
        
        group.enter()
        queue.async {
            self.work1 {
                group.leave()
            }
        }
        
        group.enter()
        queue.async {
            self.work2 {
                group.leave()
            }
        }
        
        group.notify(queue: queue) {
            print("同步完成")
        }
    }

这里可以看出来在work2的闭包的leave就会出现这个问题。

解决方法

其实这种问题完全使我们编写代码的过程中不够细心导致的,通过完善的测试用例完全可以避免问题发生,但是我们还是需要记住一句话DispatchGroup的enter和leave必须成对出现!!!

你可能感兴趣的:(DispatchGroup出现EXC_BAD_INSTRUCTION问题)