简体   繁体   中英

Has NSURLSession dataTaskWithRequest completion block always run on Main Thread?

It seems to me like something changes with iOS8.4 maybe. The completion block to my NSURLSession dataTaskWithRequest is running on the main thread rather than the thread executing the resume. Is this new and/or correct behavior?

There are many postings like this where users want to get the completion code on the main thread, but I now find it is there already (breaking my code). Here is an isolated sample:

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

With results:

threadTest on Main Thread: false Retrieved Page: <!DOCTYPE ... NSURLSession.dataTashWithRequest completion block on Main Thread: true

I just figured out the answer. The thread of the completion handler is setup in the init of the NSURLSession.

From documentation :

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

queue - A queue for scheduling the delegate calls and completion handlers. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.

My code that setup for completion on main thread:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM