2014-11-17 5 views
1

Каков правильный способ запускать методы в блоке завершения (если это даже рекомендуется)? Прямо сейчас у меня есть IBAction, который вызывает метод, который загружает информацию с блоком завершения, означающим, была ли информация получена успешно или нет. Если бы это было так, я хочу нажать контроллер представления, который отобразит эту информацию, но в данный момент ничего не происходит. Я предполагаю, что это что-то делать с основным потоком, НОД и т.д ...Нажатие контроллера просмотра внутри блока не работает

__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

Вы можете попробовать позвонить pushViewController из dispatch_asynch с задержкой 0,0 сек. Обычно это работает. – Dzmitry

ответ

1

Не уверен, если это правильный способ сделать это, но он работал.

Я добавил метод, который будет толкать ЖЕЛ на главном потоке, как так:

 [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]; 

} 
0

обновления Все UI должны быть выполнены в основном потоке. Лично я предпочитаю делать это через GCD, поскольку он создает более читаемый код, чем performSelectorOnMainThread. Тем не менее, нет ничего плохого в performSelectorOnMainThread в стороне от личных предпочтений в случае вызова одного обновления пользовательского интерфейса в основном потоке после выполнения некоторого блока завершения. Обратите внимание, что, какой бы вы ни выбрали, вы должны be consistent with what you use to guarantee that blocks are enqueued in the order you specified.

Рабочий код в стороне, однако, соглашение, которое, как представляется, использует инфраструктура Apple, состоит в том, чтобы выполнять все блоки завершения в основном потоке, если только очередь не указана как параметр метода, и в этом случае блок завершения должен выполняться в этой очереди. Поэтому в этом случае я бы рекомендовал вам отредактировать метод downloadJson класса обработчика загрузки для автоматического выполнения блока завершения в главной очереди.

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]; 
    }]; 
Смежные вопросы