为什么有时从 DISpatchQueue 调用时会出现 EXC_BAD_ACCESS?

问题描述

在以下代码中:

class dispatchQueuer: dispatchQueuerable {
    private let queue: dispatchQueue

    // MARK: - Initialization

    init(queue: dispatchQueue) {
        self.queue = queue
    }
    func asyncBackground(block: @escaping () -> Void) {
        dispatchQueue(label: "",qos: .background).async {
            block() //EXC_BAD_ACCESS
        }
    }
}

为什么会这样?

我使用它的方式如下:

    private let dispatchQueuer: dispatchQueuerable
    dispatchQueuer.asyncBackground { [weak self] in
        self?.setupTags()
        self?.setupsuppliers()
        self?.dispatchQueuer.asyncMain {
            completion?()
        }
    }

解决方法

您有数据竞争问题。部分问题在于每次调用 asyncBackground 都在一个新队列中,因此您很快就会有多个冲突队列和冲突访问。你应该把你的队列变成一个单例队列。这样,至少您将受益于串行队列,而目前您正在丢弃该队列。

请注意,您将 self.queue 声明为实例属性。这在某种程度上是个好主意,但你永远不会使用它!你也把它扔掉。就我个人而言,我会使用 static let 来获得真正的单例串行队列,并且我会使用它。

即便如此,这也不会使您的访问成为线程安全的。但它会比你现在做的好很多。