除非我使用调度主队列,为什么PopViewControllerAnimated会崩溃?

时间:2014-01-28 15:43:59

标签: ios iphone objective-c uitableview uinavigationcontroller

为了给出一些上下文,我有一个简单的UITableViewController,它用数据填充UITableView。选择一行后,我会通过创建自定义UIViewController的新实例并将其推送到导航控制器来转到详细信息屏幕:

-(void)tableView:(UITableView *)itemTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [itemTableView deselectRowAtIndexPath:indexPath animated:NO];

    NSDictionary *mydata = [self.dataRows objectAtIndex:indexPath.row];

    NameDetailViewController *NDVC = [[NameDetailViewController alloc] initWithName:[mydata objectForKey:@"Name"]
    AndEmail:[mydata objectForKey:@"Email"]
    AndID:[mydata objectForKey:@"Id"]];

    [self.navigationController pushViewController:NDVC animated:YES];
}

细节控制器本身有几个文本字段和一个更新按钮。按下更新按钮时,我更新了我的模型,然后尝试使用以下方法导航回之前的UITableViewController:

[self.navigationController popViewControllerAnimated:YES];

当我这样做时,应用程序崩溃我得到一个错误就像尼克在之前的SO帖子中得到的那样:Error when dismissing view controller - 关于断言失败的事情 - [UIKeyboardTaskQueue waitUntilAllTask​​sAreFinished](我可以提供更多详细信息)如果需要的话。)

我在调用pop来解决这个问题之前尝试了一些事情。

[self.view endEditing:YES];

以及在每个UITextfield上使用resignFirstResponder。两者都没有做任何事情。

但是,我发现我是否使用主线程:

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

似乎工作得很好。我不知道为什么会这样,并且没有非常牢固地了解它为什么会崩溃。我假设它与我的细节控制器试图在从堆栈中移除后做某事有关。

无论如何,我希望有人能帮助我理解为什么这似乎有效,如果这对我来说是一个合理的方式来解决这个问题。

1 个答案:

答案 0 :(得分:3)

有时异步API请求不会回调主线程上的委托。这可能有几个原因,但如果回调不在主线程上,那么在进行任何更新UI之前,您需要确保切换到主线程。

作为检查,您可以确定当前是否正在主线程上运行:

if ([NSThread isMainThread]) {
    NSLog(@"Yay!");
} else {
    NSLog(@"Humph, switching to main");
    dispatch...
}