在回调块

时间:2018-03-09 10:14:17

标签: ios objective-c uinavigationcontroller

我的任务是在更大的Objective-C应用程序中进行一些小的调整。

我尝试做的是当用户点击列表中的某个项目时,将执行计算,并且根据结果,导航应弹回root并显示错误。因为我无法访问计算完成的类中的NavigationController,所以我尝试传递一个"回调块"。

[self.baseBehaviour processInfo:info completion: ^(BOOL finished) {
  NSLog(finished ? @"YES" : @"NO");
  // pop back to root controller
  [self.navigationController popToRootViewControllerAnimated:YES];
 }];

我传递该块直到计算完成并调用回调。它似乎工作正常,因为我可以在日志中看到YES或NO,但导航不会由于某种原因被触发。它似乎也不是一个范围问题,因为self似乎是相同的引用(我甚至试图为navigationController创建一个新的变量,但这也没有帮助)。

如果我取出[self.navigationController popToRootViewControllerAnimated:YES];并将其移出回调(因此立即执行),它就能完美运行。但显然这对我没有帮助,因为当时我并没有确定是否需要回去。

我是否遗漏了某些东西,或者有没有办法看到(在调试器中)为什么动画没有被触发?

感谢您的帮助。

编辑:

我在测试时尝试了这个,但它似乎也没有用:

    [self.baseBehaviour processInfo:self.info completion: ^(BOOL finished) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(finished ? @"YES" : @"NO");
            // pop back to root controller
            [self.navigationController popToRootViewControllerAnimated:YES];
        });
    }];

EDIT2:

看起来它毕竟可能是一个范围问题。我注意到,当我执行``时,它在调试器中是零。

NSArray *viewCtrls = [self.navigationController viewControllers]; // 3 elements

[self.baseBehaviour processInfo:self.info completion: ^(BOOL finished) {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(finished ? @"YES" : @"NO");
        // pop back to root controller
        NSArray *viewCtrls = [self.navigationController viewControllers]; // nil
        [self.navigationController popToRootViewControllerAnimated:NO];
    });
}];

我怎样才能通过"什么东西进入回调块,比如navigationController?

3 个答案:

答案 0 :(得分:1)

在主线程中执行,例如:

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

这可能有助于你

答案 1 :(得分:1)

完成块将在辅助线程中执行。推送或弹出视图控制器必须位于主线程中。所以在那里创建一个主线程并弹出到根控制器

    [self.baseBehaviour processInfo:info completion: ^(BOOL finished) {
      NSLog(finished ? @"YES" : @"NO");
      // pop back to root controller
dispatch_async(dispatch_get_main_queue(), ^{[self.navigationController popToRootViewControllerAnimated:YES];});


     }];

您在评论中的问题: - 由于另一个动画(推送)已经在运行,动画是否可能无法触发? 答案: - 如果您遇到动画故障问题,请在弹出视图控制器时传递NO,如下所示: -

dispatch_async(dispatch_get_main_queue(), ^{[self.navigationController popToRootViewControllerAnimated:NO];});

答案 2 :(得分:1)

只需在主线程上运行它。

dispatch_async(dispatch_get_main_queue(), ^{
    [self.navigationController popToRootViewControllerAnimated:true];
});