是否在主线程上调用了NSURLSessionDataTask完成块?

时间:2016-03-28 02:14:43

标签: ios objective-c multithreading

我一直试图找出什么时候可以“只输入我需要做的事情”,当我需要具体说明我在做什么样的工作时会做什么样的工作。

据我所知,我应该只更新主线程上的UI。这是否意味着做这样的事情是不可行的?我应该把它放入GDC电话吗?

[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

}];

这就是UI部分。现在,让我们假设我的课堂上有一个NSMutableArray。我会通过点击UIButton来添加或删除此数组中的对象。然后,我又有一个NSURLSessionDataTask去某个服务器获取一些数据并将其加载到我的NSMutableArray中,如下所示:

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

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

}];

这不是UI操作。这是否需要包含在GDC调用中以避免在完成块运行时添加对象(即[myMutableArray insertObject:someObj atIndex:4];)的按钮点击之间的竞争条件中崩溃,或者这些设计是否相互冲突?

我遗漏了所有错误处理,专注于手头的问题。

1 个答案:

答案 0 :(得分:4)

TLDR :在完成处理程序中调用else if (fullScreen == fullScreen) {...}无需任何费用,所以就这样做。

长答案

让我们看一下文档,不管吗?

  

dispatch_async(dispatch_get_main_queue()...加载请求完成时调用的完成处理程序。此处理程序在委托队列上执行。

委托队列是您使用completionHandler创建NSURLSession时传入的队列。如果那不是你创建这个NSURLSession的方式,那么我建议你不做任何假设关于调用完成处理程序的队列。如果您没有将sessionWithConfiguration:delegate:delegateQueue:作为此参数传递,那么您将处于后台队列中,并且应该在执行非线程安全的任何操作之前跳转到主队列。

现在的问题是:

  • 更新UI并与表视图对话是否可以线程安全?不,你必须只在主队列上做这些事情。

  • 设置[NSOperationQueue mainQueue]是否可以线程安全?不,因为您将在两个线程(主要队列,您通常与此属性进行通信,以及队列,无论它是什么)之间共享属性myMutableArray。< / p>