优化的方法来搜索iphone范围内的设备IP地址

时间:2015-09-02 15:29:51

标签: ios iphone algorithm swift search

我有情况在哪里我必须搜索**路由器**的IP地址,我知道它的范围是从范围163.289.2.0到163.289.2.255。 我知道这不是一个很好的搜索方式。

for i in 1... 255 {

var str = "163.289.2." + "i"
var tempIP = Ping.getIPAddress(str)

if(tempIP == true)
{
   break;
}

}

现在我的问题是我的自定义类Ping.getIPAddress()花费3秒来获取给定IP值的结果。因此,对于255次搜索,大约需要765秒(12.75分钟)。我有限制搜索应该在最多2分钟内完成。所以无论如何我可以使用swift在iPhone中实现这一点。

我必须只使用这个自定义函数Ping.getIPAddress(),如果存在给定的IP地址则为true,否则为false。

请向我提供解决此问题的示例或参考或方法。

使用NSOperationQueue并将MaxConcurrentOperationCount设置为10会不错?

1 个答案:

答案 0 :(得分:14)

同步方法

如果我们只在完成前一个呼叫后才对Ping.getIPAddress(str)执行每个呼叫,我们需要等待(3秒* 256)= 768秒。

enter image description here

异步方法

另一方面,我们可以对Ping.getIPAddress(str)进行多次并发调用。

enter image description here

假Ping类

这是我为测试你的功能而创建的一个类。

class Ping {
    class func getIPAddress(str:String) -> Bool {
        sleep(3)
        return str == "163.289.2.255"
    }
}

如您所见,该类确实等待3秒(以模拟您的方案),然后仅在传递的trueip时返回163.289.2.255。这使我能够复制最坏的情况。

解决方案

这是我准备的课程

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)
                        }
                    }
                }
            }
        }
    }
}

该类对Ping.getIPAddress(...)执行 256次异步调用

256个异步闭包的结果由以下代码处理:

dispatch_async(serialQueue) {
    if !resultFound {
        resultFound = foundThisOne
        numProcessed++
        if resultFound {
             completion(existingIP:ip)
        } else if numProcessed == 256 {
             completion(existingIP: nil)
        }
    }
}

上一段代码(从第2行到第9行)在我的队列serialQueue中执行。这里256个不同的闭包运行同步

  1. 这对于确保对变量resultFoundnumProcessed的一致访问至关重要;
  2. 另一方面,从性能的角度来看这不是问题,因为这段代码非常快(只是一堆算术运算)
  3. 测试

    这就是我从标准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.
        }
    
    
    }
    

    结论

    最后,这是我在iOS模拟器上测试时的输出。请注意,这是最糟糕的情况(因为上次检查的号码是有效的IP)。

    2015-09-04 20:56:17 +0000
    "existingIP: Optional(\"163.289.2.255\")"
    2015-09-04 20:56:29 +0000
    

    它只有12秒!

    希望这有帮助。