在块内推动视图控制器不工作

时间:2014-11-17 02:22:43

标签: ios objective-c xcode objective-c-blocks

在完成块中触发方法的正确方法是什么(如果甚至建议这样做)?现在,我有一个IBAction调用一个方法,该方法使用完成块下载信息,表示信息是否成功检索。如果是,我想推送一个显示该信息的视图控制器,但此刻,什么也没发生。我猜它与主线程,gcd等有关...

__weak YTTMSetupViewController *weakSelf = self;
    [mc downloadJson:^(BOOL success) {
            if(success){
                NSLog(@"sucess. metric count - %i",(int)mc.collection.count);

                //info was downloaded. Push new view controller with info
                YTTMMetricTableViewController *mtvc = [self.storyboard instantiateViewControllerWithIdentifier:@"YTTMMetricTableViewController"];
                mtvc.group = (WAGroup*)[[WAMetricCollection sharedInstance].collection lastObject];
                mtvc.hidesBottomBarWhenPushed = YES;
                [weakSelf.navigationController pushViewController:mtvc animated:YES];
            }
            else{
                NSLog(@"failure");
                //display failure UI
            }
            NSLog(@"end of downloading");
            [HUD dismissAfterDelay:0.5f animated:YES];
        }];

3 个答案:

答案 0 :(得分:1)

不确定这是否是正确的方法,但它有效。

我添加了一个方法,将主要线程上的vc推送到:

        [weakSelf performSelectorOnMainThread:@selector(pushDetail) withObject:nil waitUntilDone:YES];

完成代码:

__weak YTTMSetupViewController *weakSelf = self;
    [mc downloadJson:^(BOOL success) {
            if(success){
                NSLog(@"sucess. metric count - %i",(int)mc.collection.count);

                //info was downloaded. Push new view controller with info
                [weakSelf performSelectorOnMainThread:@selector(pushDetail) withObject:nil waitUntilDone:YES];
            }
            else{
                NSLog(@"failure");
                //display failure UI
            }
            NSLog(@"end of downloading");            
        }];

}

-(void)pushDetail{
    __weak YTTMSetupViewController *weakSelf = self;
    YTTMMetricTableViewController *mtvc = [self.storyboard instantiateViewControllerWithIdentifier:@"YTTMMetricTableViewController"];
    mtvc.group = (WAGroup*)[[WAMetricCollection sharedInstance].collection lastObject];
    mtvc.hidesBottomBarWhenPushed = YES;
    [weakSelf.navigationController pushViewController:mtvc animated:YES];

}

答案 1 :(得分:1)

您可以尝试使用dispatch_asynch块来包装调用...

__weak YTTMSetupViewController *weakSelf = self;
    [mc downloadJson:^(BOOL success) {
        if(success){
            NSLog(@"sucess. metric count - %i",(int)mc.collection.count);

            dispatch_async(dispatch_get_main_queue(), ^{
                //info was downloaded. Push new view controller with info
                YTTMMetricTableViewController *mtvc = [self.storyboard instantiateViewControllerWithIdentifier:@"YTTMMetricTableViewController"];
                mtvc.group = (WAGroup*)[[WAMetricCollection sharedInstance].collection lastObject];
                mtvc.hidesBottomBarWhenPushed = YES;
                [weakSelf.navigationController pushViewController:mtvc animated:YES];
            });
        }
        else{
            NSLog(@"failure");
            //display failure UI
        }
        NSLog(@"end of downloading");
        [HUD dismissAfterDelay:0.5f animated:YES];
    }];

答案 2 :(得分:0)

必须在主线程上执行所有UI更新。我个人更喜欢通过GCD执行此操作,因为它生成的代码比performSelectorOnMainThread更易读。但是,除了个人偏好之外,在执行某个完成块后在主线程上调用单个UI更新的情况下,performSelectorOnMainThread没有任何问题。请注意,无论您选择哪一个,都应该be consistent with what you use to guarantee that blocks are enqueued in the order you specified

除了工作代码之外,Apple的框架似乎使用的约定是在主线程上执行所有完成块,除非将队列指定为方法参数,在这种情况下应该在该队列上执行完成块。所以在这种情况下,我建议您编辑下载处理程序类的downloadJson方法,以自动在主队列上执行完成块。