什么是iOS中的dispatch_async功能?

时间:2015-08-13 04:36:37

标签: ios grand-central-dispatch

我试图通过阅读https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/

来理解这一点

但这太令人困惑了。我知道以下代码必须对排队任务执行某些操作。我认为排队意味着等待?而且我不确定任务是什么。而且我知道它以某种方式加速了代码内部代码的执行。尽管如此,我在使用时以及为什么使用它时都非常困惑。

dispatch_async(dispatch_get_main_queue(), { () -> Void in    
})

上面的代码可以在这段代码中找到:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var cityTextField: UITextField!
@IBOutlet weak var resultLabel: UILabel!
@IBAction func findWeather(sender: AnyObject) {
    let url = NSURL(string: "http://www.weather-forecast.com/locations/Riverside/forecasts/latest")!
    let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in
        if let urlContent = data {
            let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)

            var websiteArray = webContent!.componentsSeparatedByString("3 Day Weather Forecast Summary:</b><span class=\"read-more-small\"><span class=\"read-more-content\"> <span class=\"phrase\">")
            let tempText = websiteArray[1]

            websiteArray = tempText.componentsSeparatedByString("</span></span></span></p><div class=\"forecast-cont\"><div class=\"units-cont\"><a class=\"units metric active\">&deg;C</a><a class=\"units imperial\">&deg;")
            print(websiteArray[0])
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.resultLabel.text = websiteArray[0]
            })

        }
    }
    task?.resume()
}

2 个答案:

答案 0 :(得分:3)

简而言之,dispatch_async块中的代码将在您选择的队列(线程)上异步执行(主队列是UI线程)

为什么它加速你的代码是因为self.resultLabel.text = websiteArray[0]不在主线程上运行的块内会使代码在不是UI线程的不同线程上执行(因为NSURLSession完成处理程序)发生在不同的线程上),更新UI不在UI线程上会导致奇怪的行为(主要是更新UI时的随机延迟)

如果您将dispatch_get_main_queue()更改为其他队列,您会看到完全相同的行为,因为根本没有该块

这可能有助于澄清在哪个线程上执行的代码行:

@IBAction func findWeather(sender: AnyObject) { //function called from UI thread
    let url = NSURL(string: "http://www.weather-forecast.com/locations/Riverside/forecasts/latest")! //UI thread
    let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in //UI thread, but this function call now creates its own thread that the block will run on
//Not UI Thread ----------------------------
        if let urlContent = data {  
            let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)

            var websiteArray = webContent!.componentsSeparatedByString("3 Day Weather Forecast Summary:</b><span class=\"read-more-small\"><span class=\"read-more-content\"> <span class=\"phrase\">")
            let tempText = websiteArray[1]

            websiteArray = tempText.componentsSeparatedByString("</span></span></span></p><div class=\"forecast-cont\"><div class=\"units-cont\"><a class=\"units metric active\">&deg;C</a><a class=\"units imperial\">&deg;")
            print(websiteArray[0])
// -----------------------------------------
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.resultLabel.text = websiteArray[0] //UI thread
            })
//Not UI Thread again, if there was code here
        }
    }
    task?.resume() //inside the original function, so its on the UI thread
}

答案 1 :(得分:0)

dispatch_async(dispatch_get_main_queue(), { () -> Void in    
                self.resultLabel.text = websiteArray[0]
})

以上功能用于在主线程上进行更新,任何UI更新相关操作都应在主线程和&amp ;;因为dispatch_get_main_queue()作为参数传递。

如果您删除此块&amp;尝试设置没有它的结果值文本,然后它可能不会更新UI或需要时间来更新它。

尝试设置不同的队列以使您更清楚。