2017-07-02 42 views
0

做UI更新必须根据这个问题https://stackoverflow.com/a/23155684/1898829为什么我的UI更新,当我explicitiy离开了回归主线程

[[session dataTaskWithRequest:request 
      completionHandler:^(NSData *data, NSURLResponse *response, 
           NSError *error) { 
       if (data != nil) { 
        NSDictionary *responseDictionary = 
        [NSJSONSerialization JSONObjectWithData:data 
                options:kNilOptions 
                 error:&error]; 
//      dispatch_async(dispatch_get_main_queue(), ^{ 
          CarListModel *carListModel = [[CarListModel alloc] 
                  initWithArray:responseDictionary[@"placemarks"]]; 
          completion(carListModel, error); 
//      }); 
        } else { 
         dispatch_async(dispatch_get_main_queue(), ^{ 
          completion(nil, error); 
         }); 
        } 
       }] resume]; 

当注释掉dispatch_async(dispatch_get_main_queue()要在主线程上完成,^{我的应用仍然和以前一样工作,我的桌面视图得到更新,我的活动指示灯停止。

这个完成块转到一个视图模型,该视图模型有一个完成块到视图控制器。必须回到主线上。

为什么我的UI不会被阻塞或有可能是它返回到主线程没有我明确地与

dispatch_async(dispatch_get_main_queue(), ^{ 
+0

您不是“回到”主线程。主线程并行运行。 '-dataTaskWithRequest'可能使用在anthoer线程上运行的队列。因此你不能阻塞主线程。只有主线程上的代码才能阻塞主线程。 –

+0

那么我的UI在主线程上的更改没有完成,并且如果他们正在主线程上完成,为什么? – user1898829

+0

如果您在派发到主队列之外运行完成处理程序,它会在主线程之外执行。由于我不知道完成处理程序的代码,所以我不能说在什么队列上做了什么。 –

回答

1

将它设置你是正确的UI更新必须在主线程中完成。你错误地认为在主线程中不这样做会导致不采取任何行动。如果只有这种情况。如果您不在主线程上执行UI更新,则应用程序可能会在任何时候以奇怪且意想不到的方式失败。这意味着它几分钟后可能会崩溃。动画可能突然停止工作。视图可以随机消失或出现。导航栏可能不在场所。换句话说,行为是不确定的。

因此,你应该

1)总是用dispatch_async(dispatch_get_main_queue(), ^{从后台线程

2)如果你有一个方法可能不小心将它从后台线程调用更新UI的时候,用什么样保护他们:

if (![NSThread mainThread]) { 
    // log to crash reporter without crashing 
    NSError* error = [NSError errorWithDomain:@"accessing UI outside of main thread" code:-1 userInfo:nil]; 
    [[Crashlytics sharedInstance] recordError:error withAdditionalUserInfo:@{@"file":__FILE__, @"line":@(__LINE__)}]; 
    return; 
} 
相关问题