Search code examples
iosswiftexc-bad-access

Why sometimes do I have EXC_BAD_ACCESS when called from DIspatchQueue?


In following code:

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
        }
    }
}

Why it happens?

I use it the following way:

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

Solution

  • You have data race issues. The problem is partly that every call to asyncBackground is on a new queue, so you rapidly have multiple colliding queues and colliding accesses. You should turn your queue into a singleton queue. That way at least you will have the benefit of a serial queue, which at present you are throwing away.

    Note that you declare self.queue as an instance property. That's a good idea to some extent, but then you never use it! You throw that away too. Personally I would use static let to get a true singleton serial queue, and I would use it.

    Even then, that won't make your accesses thread-safe. But it will be a lot better than what you're doing now.