Reputation: 5525
My goal is to perform a resource-heavy operation asynchronously, and ensure that it is completed before returning the objects.
This is the structure:
func modifyGadgets() -> [Gadget] {
var gadgetsToModify = [Gadget]() //this is already populated elsewhere
DispatchQueue.global(qos: .userInitiated).async {
//Do something to the original gadgets
for gadget in gadgetsToModify {
modifyThisGadget(gadget)
}
DispatchQueue.main.async {
return gadgetsToModify //I get a warning here saying gadgetsToModify is unused
}
}
}
In addition to the warning, I also don't get any of the Gadget
items back.
How should I structure this so I am able to return the items once it is finished?
Thanks.
Upvotes: 0
Views: 49
Reputation: 58149
You should use a completion handler for this.
func modifyGadgets(_ callback: @escaping ([Gadget]) -> ()) {
var gadgetsToModify = [Gadget]()
DispatchQueue.global(qos: .userInitiated).async {
for gadget in gadgetsToModify {
modifyThisGadget(gadget)
}
DispatchQueue.main.async {
callback(gadgetsToModify)
}
}
}
You can use it this way:
modifyGadgets { gadgets in
print(gadgets)
}
Upvotes: 3
Reputation: 17060
If the operation is asynchronous, you will not be able to return a value in this way. What you want to do instead is to take a closure as a completion handler:
func modifyGadgets(completionHandler: @escaping ([Gadget]) -> ()) {
let gadgets = ...
DispatchQueue.global(qos: .userInitiated).async {
//Do something to the original gadgets
for eachGadget in gadgets {
modifyThisGadget(eachGadget)
}
completionHandler(gadgets)
}
}
Then you can call it like this:
modifyGadgets { gadgets in
// do something with gadgets
}
Upvotes: 2