从块返回导航

时间:2013-12-28 20:18:04

标签: ios multithreading uinavigationcontroller

我认为我在后台线程上发生了UX操作。在使用块的方法中,我正在调用的成功:

[self.navigationController popViewControllerAnimated:TRUE]; 

我遇到了崩溃,所以我认为检查当前线程并调用performSelectorOnMainThread可能会解决这个问题,但我不知道如何设置调用的@selector部分。

[self performSelectorOnMainThread:@selector([self.navigationController popViewControllerAnimated:TRUE]) withObject:nil waitUntilDone:NO];

无效。什么是正确的语法?

2 个答案:

答案 0 :(得分:56)

要强制方法在主线程上执行,您可以使用:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.navigationController popViewControllerAnimated:TRUE]; 
});

答案 1 :(得分:6)

严格地说,由于-performSelectorOnMainThread:的工作方式的限制,你无法直接做你想做的事。但是,无论在哪个类self中,您都可以定义这样的方法:

- (void)doPop {
  [self.navigationController popViewControllerAnimated:YES];
}

然后

[self performSelectorOnMainThread:@selector(doPop)];

详细说明语法不起作用的原因:

选择器传递给-performSelectorOnMainThread:必须是一个不带参数的选择器,或某种id的单个参数。虽然-popViewControllerAnimated:是一个采用单个参数的选择器,但该参数的类型为BOOL(顺便说一下,使用YESNO而不是TRUE和{ {1}})。

同样,FALSE将只是方法的名称,而不是您想要调用它的对象(在本例中为@selector)。

从消息传递对象的角度考虑它。您希望self.navigationController对象在主线程上执行self.navigationController选择器,因此您将以这种方式构造消息传递:

-popViewControllerAnimated:

但问题又出现了必要的论点。因此,由于您无法以这种方式直接调用[self.navigationController performSelectorOnMainThread:@selector(popViewControllerAnimated:) withObject:nil waitUntilDone:NO]; ,这就是我的上述建议。它允许你根据它的语义调用pop,然后仍然用它的语义正确地调用perform