简体   繁体   中英

Are NSURLSessionDataTask completion blocks called on the main thread?

I have been trying to figure out when it's okay to "just type in what I need done" and when I need to be specific about what kind of work I am doing on what kind of thread.

As I understand I should only update the UI on my main thread. Does this mean that it's not okay to do something like this? Should I put this into a GDC call?

[sessionManager dataTaskWithRequest:aRequest completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

    someUILabel.text = @"Hello!"; // Updating my UI
    [someTableView reloadData]; // Ask a table view to reload data

}];

That's it for the UI part. Now, let's assume I had an NSMutableArray somewhere in in my class. I would be adding or removing objects to this array by for instance tapping a UIButton . Then again I have a NSURLSessionDataTask going to a server somewhere to get some data and load it into my NSMutableArray , like so:

[sessionManager dataTaskWithRequest:aRequest completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

    myMutableArray = [[responseObject objectForKey:@"results"] mutableCopy];

}];

This is not a UI operation. Does this need to be wrapped in a GDC call to avoid crashing in a race condition between my button-tap adding an object (ie [myMutableArray insertObject:someObj atIndex:4]; ) while the completion block runs, or are these designed to not clash into each other?

I have left out all error handling to focus on the question at hand.

TLDR : It costs you nothing to call dispatch_async(dispatch_get_main_queue()... inside your completion handler, so just do it.

Long Answer :

Let's look at the documentation, shall we?

completionHandler The completion handler to call when the load request is complete. This handler is executed on the delegate queue.

The delegate queue is the queue you passed in when you created the NSURLSession with sessionWithConfiguration:delegate:delegateQueue: . If that's not how you created this NSURLSession, then I suggest you make no assumptions about what queue the completion handler is called on. If you didn't pass [NSOperationQueue mainQueue] as this parameter, you are on a background queue and you should break out to the main queue before doing anything that is not thread-safe.

So now the question is:

  • Is it thread-safe to update the UI and talk to the table view? No, you must do those things only on the main queue.

  • Is it thread-safe to set myMutableArray ? No, because you would then be sharing a property, self.myMutableArray , between two threads (the main queue, where you usually talk to this property, and this queue, whatever it is).

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