在完成块中触发方法的正确方法是什么(如果甚至建议这样做)?现在,我有一个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];
}];
答案 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
方法,以自动在主队列上执行完成块。