I want to run a for loop
with background code, that has something happen once it's finished iterating through every item. To do this without background code would be simple, like this:
for aString: String in strings {
if string.utf8Length < 4 {
continue
}
//Some background stuff
}
//Something to do upon completion
But to include background code in there means that the code to perform upon completion gets performed before all items are dealt with.
for aString: String in strings {
if string.utf8Length < 4 {
continue
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
//Some background stuff
}
}
//Something to do upon completion
I'm wondering if it's possible to do that.
Consider using a dispatch group. This provides a mechanism that notifies you when the dispatched tasks finish. So rather than dispatch_async
, use dispatch_group_async
:
let group = dispatch_group_create();
for aString: String in strings {
if aString.utf8Length >= 4 {
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
//Some background stuff
}
}
}
dispatch_group_notify(group, dispatch_get_main_queue()) {
// whatever you want when everything is done
}
FYI, here is an operation queue rendition of the same idea (though something that constrains the number of concurrent operations).
let queue = NSOperationQueue()
queue.name = "String processing queue"
queue.maxConcurrentOperationCount = 12
let completionOperation = NSBlockOperation() {
// what I'll do when everything is done
}
for aString: String in strings {
if aString.utf8Length >= 4 {
let operation = NSBlockOperation() {
// some background stuff
}
completionOperation.addDependency(operation)
queue.addOperation(operation)
}
}
queue.addOperation(completionOperation)