0

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.

1 Answers1

2

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()
    }
}
Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
  • 1
    This should do it ;) BTW, his original `update` function was using an unnecessary *completion block* on a clearly synchronous function. Doesn’t make much sense to me... – Paulo Mattos Oct 12 '17 at 12:53
  • @AndriyTrubchanin: Using notify has not solved your issue? – Puneet Sharma Oct 12 '17 at 13:14
  • 1
    @Puneet Sharma Using notify has solved my issue. The code has became more complicated and I searched the way to make it more simple. Anyway it works, thanks. – Andriy Trubchanin Oct 12 '17 at 13:47
  • @AndriyTrubchanin: Happy to help. You can break your existing code into relevant functions and call them from other functions. – Puneet Sharma Oct 12 '17 at 13:49
  • @PuneetSharma I have kind of the same thing but not works. https://paste.ubuntu.com/p/cs2XYj6gdD/ ... This happens only first time when I didn't have an apple id to test subscriptions and after that, it works when restarting the app. I don't understand why it just not handle completion handler first time? – Bhavin Bhadani Mar 22 '19 at 04:22
  • @PuneetSharma Can you help me on this? https://stackoverflow.com/questions/55294986/dispatchgroup-issue-when-authentcate-apple-id – Bhavin Bhadani Mar 22 '19 at 07:46