NSURLSession dataTaskWithRequest完成块是否始终在主线程上运行?

时间:2015-07-17 12:57:49

标签: ios multithreading swift

在我看来,iOS8.4可能会发生一些变化。我的NSURLSession dataTaskWithRequest的完成块正在主线程上运行,而不是执行恢复的线程。这是新的和/或正确的行为吗?

有许多帖子如this,用户希望在主线程上获取完成代码,但我现在发现它已经存在(破坏了我的代码)。这是一个孤立的样本:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
        self.threadTest()
    }
    return true
}

func threadTest() {
    println("threadTest on Main Thread: \(NSThread.currentThread().isMainThread)")
    let urlString = "http://www.apple.com/contact/"
    let url = NSURL(string:urlString)
    var request = NSMutableURLRequest(URL: url!)
    var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())

    var task = session.dataTaskWithRequest(request) {
        (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in

        if error != nil {
            print("Error: \(error.localizedDescription)")
        }
        else {
            if let result = NSString(data: data, encoding:NSASCIIStringEncoding)                    {
                let partial = result.substringToIndex(10)
                println("Retrieved Page: \(partial)...")
                println("NSURLSession.dataTashWithRequest completion block on Main Thread: \(NSThread.currentThread().isMainThread)")
            }
        }
    }
    task.resume()
}

结果:

  主线程上的

threadTest:false   检索页面:<!DOCTYPE ...   主线程上的NSURLSession.dataTashWithRequest完成块:true

1 个答案:

答案 0 :(得分:6)

我刚刚想出答案。完成处理程序的线程在NSURLSession的init中设置。

来自documentation

init(configuration configuration: NSURLSessionConfiguration, delegate delegate: NSURLSessionDelegate?, delegateQueue queue: NSOperationQueue?)

queue - 用于调度委托调用和完成处理程序的队列。如果为nil,则会话创建一个串行操作队列,用于执行所有委托方法调用和完成处理程序调用。

我在主线程上设置完成的代码:

var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())