I have situation where-in i have to search IP address of **router ** and I know only it\'s range is from range 163.289.2.0 to 163.289.2.255. I know this is not good way to s
If we perform each call to Ping.getIPAddress(str)
only after the previous one has completed of course we need to wait for (3 seconds * 256) = 768 seconds.
On the other hand we can perform several concurrent calls to Ping.getIPAddress(str)
.
This is a class I created to test your function.
class Ping {
class func getIPAddress(str:String) -> Bool {
sleep(3)
return str == "163.289.2.255"
}
}
As you see the class does wait for 3 seconds (to simulate your scenario) and then returns true
only if the passed ip
is 163.289.2.255
. This allows me to replicated the worst case scenario.
This is the class I prepared
class QuantumComputer {
func search(completion:(existingIP:String?) -> ()) {
var resultFound = false
var numProcessed = 0
let serialQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)
for i in 0...255 {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.value), 0)) {
var ip = "163.289.2." + "\(i)"
let foundThisOne = Ping.getIPAddress(ip)
dispatch_async(serialQueue) {
if !resultFound {
resultFound = foundThisOne
numProcessed++
if resultFound {
completion(existingIP:ip)
} else if numProcessed == 256 {
completion(existingIP: nil)
}
}
}
}
}
}
}
The class performs 256 asynchronous calls to Ping.getIPAddress(...)
.
The results from the 256 async closures is processed by this code:
dispatch_async(serialQueue) {
if !resultFound {
resultFound = foundThisOne
numProcessed++
if resultFound {
completion(existingIP:ip)
} else if numProcessed == 256 {
completion(existingIP: nil)
}
}
}
The previous block of code (from line #2 to #9) is executed in my queue serialQueue
. Here the 256 distinct closures run synchronously.
resultFound
and numProcessed
;And this is how I call it from a standard ViewController.
class ViewController: UIViewController {
var computer = QuantumComputer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
debugPrintln(NSDate())
computer.search { (existingIP) -> () in
debugPrintln("existingIP: \(existingIP)")
debugPrintln(NSDate())
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Finally this is the output when I test it on my iOS simulator. Please remind that this is the worst case scenario (since the last checked number is a valid IP).
2015-09-04 20:56:17 +0000
"existingIP: Optional(\"163.289.2.255\")"
2015-09-04 20:56:29 +0000
It's only 12 seconds!
Hope this helps.