Andriy Trubchanin
Andriy Trubchanin

Reputation: 110

Swift: Deadlock with DispatchGroup

I've got some issue with CoreData concurrency. I can't do context.perform while a destination thread is blocked with DispatchGroup.

Here is a simple example which shows the issue:

func upload(objects: [NSManagedObject]) {
    let group = DispatchGroup()
    for object in objects {
        group.enter()
        upload(object) {
            group.leave()
        }
    }
    group.wait()    // current thread is blocked here

    someAdditionalWorkToDoInSameThread()
}

func upload(object: NSManagedObject, completion: ()->()) {
    let context = object.managedObjectContext
    performAlamofireRequest(object) {
        context.perform {
            // can't reach here because the thread is blocked
            update(object)
            completion()
        }
    }
}

Please, help me to reimplement this properly. Thanks.

Upvotes: 1

Views: 2723

Answers (1)

Puneet Sharma
Puneet Sharma

Reputation: 9484

Using notify on dispatch group instead of wait, should resolve your issues.

Calling wait() blocks current thread for completion of previously submitted work.
notify(queue:execute:) will notify the queue that you passed as argument that the group task has been completed.

func upload(objects: [NSManagedObject], completion: ()->()) {
    let group = DispatchGroup()
    for object in objects {
        group.enter()
        upload(object) {
            group.leave()
        }
    }
    group.notify(queue: DispatchQueue.main) {
         completion()
    }
}

Upvotes: 5

Related Questions