This is my decision
Fake ConnectedDevices Class
This is a fake class that I created to test your script. As you can see, the getAllDetails method simulates database access. It waits 10 seconds and then returns true only if the input parameter is 40 . Thus, we can test this code in the worst case, since all calls must be made.
class ConnectedDevices { class func getAllDetails(i:Int) -> Bool { sleep(10) return i == 40 } }
Class loader
This is a class that will interact with Grand Central Dispatch .
class Loader { private var numProcessed = 0 private let dbQueue = dispatch_queue_create("dbQueue", DISPATCH_QUEUE_SERIAL) private let utilityQueue = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0) func search(completion:(result:Int?)->()) { dispatch_async(utilityQueue) { for group in [1, 11, 21, 31] { if let indexFound = self.search10(group) { completion(result: indexFound) return } } completion(result: nil) } } private func search10(startingIndex:Int) -> Int? { var indexFound : Int? dispatch_apply(10, utilityQueue) { (delta) -> () in let found = ConnectedDevices.getAllDetails(startingIndex + delta) dispatch_sync(self.dbQueue) { self.numProcessed++
search10 (startingIndex: Int)
This synchronous method takes Int as a parameter and makes 10 simultaneous calls to ConnectedDevices.getAllDetails . Each call is made with the addition of startingIndex in delta ( delta goes from 0 to 9 ).
The result is synchronously placed in a synchronous queue, where numProcessed safely grows. If found true , then the win index ( startingIndex + delta ) is returned.
If found never becomes true , nil returned.
Search()
This is the asych method. This is a simple for loop where group variables are populated with 1 , then 11 , then 21 and finally 31 .
On every call to search10 . If it returns an Int value, the value is passed to completion , otherwise the loop continues.
If 4 cycles are executed without the value returned from search10 , then nil is passed to completion .
Using
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() debugPrintln("Begin: \(NSDate())") Loader().search { (result) -> () in debugPrintln(result) debugPrintln("End: \(NSDate())") } } }
Test
For 40 consecutive calls to ConnectedDevices.getAllDetails(...) 40 * 10 = 400 seconds required.
In my iPhone Simulator without any optimization enabled this code requires 120 seconds .
Hope this is what you need.
PS
- Note that I am increasing
numProcessed if the current result is true . - I did not find the target
isConditionTrue , so I deleted it.