Reputation: 8043
I have many asynchronous tasks that need to all be completed before I can move on, so I'm using a DispatchGroup. However, I am able to tell if one of the tasks fails early, and I would usually call a completion handler.
If I leave the scope of the function by calling a completion handler, what happens to the DispatchGroup?
Is the memory allocated forever? Is it possible that if leave is called enough times eventually (maybe due to a bug) that the notify block can still be called?
Example:
func example(completion: @escaping (Bool) - Void) {
let group = DispatchGroup()
group.enter()
asyncFunction1 {
if result == false {
completion(false)
} else {
group.leave()
}
}
group.enter()
asyncFunction2 { result in
if result == true {
group.leave()
}
}
group.notify(queue: .main) {
completion(true)
}
}
In the example above I have two asynchronous functions. The first function might call completion(false)
, and the second function only calls leave
on success. While it might not be the best example of code, these conditions are possible. What happens to the notify block?
Upvotes: 3
Views: 3147
Reputation: 8043
From the swift's source on GCD: https://github.com/apple/swift-corelibs-libdispatch/blob/master/src/semaphore.c
It seems the block will be allocated and never released. Meaning, the memory the block retains will also never be released.
Upvotes: 5
Reputation: 534958
I'm wondering what happens when leave is never called. Just because it must be called, doesn't mean it always will be called.
Well, don't "never call" it. You must arrange your code so that leave
is called by every possible exit path. If you can't, don't use dispatch groups.
If necessary, you can pass the dispatch group itself into the completion handler so that it can call leave
for you. But one way or another, call leave
.
Upvotes: -1
Reputation: 23078
The dispatchgroup must be notified whenever a code block enters the group as well as whenever a codeblock leaves the group.
That means, dispatchGroup.leave()
must be called regardless of success or failure of your function.
When all blocks are finished, the dispatchgroup gets notified.
Upvotes: 1