2012-03-29 25 views
2

在处理线程和主线程上,获得标签更改为HUD的最佳方式是什么?多个派发使用MBProgressHUD

[activitySpinner startAnimating]; 
    //[HUD setLabelText:@"Connecting"]; 
    //[HUD showUsingAnimation:YES]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
     hud.labelText = @"Connecting1"; 

     NSString *url = [NSString stringWithFormat:@"my URL", [dataObj.pListData objectForKey:@"API_BASE_URL"], userField.text, passwordField.text]; 
     NSLog(@"Login: %@",url); 
     NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 

     NSError *error;   
     NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
     [HUD setLabelText:@"Processing"]; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if ([json objectForKey:@"authToken"] != nil) { 
       [HUD setLabelText:@"Logging In"]; 
       NSLog(@"Found authtoken %@", [json objectForKey:@"authToken"]); 
       [dataObj setAuthToken:[json objectForKey:@"authToken"]]; 
       [dataObj setLocationId:[json objectForKey:@"c_id"]]; 

       [dataObj setStaffId:[[json objectForKey:@"staffOrRoomsId"] integerValue]]; 
       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
       [HUD setLabelText:@"Downloading"]; 

       }); 

       [self getAllData]; 
       [self performSegueWithIdentifier:@"segueToRootController" sender:self]; 


      } else { 
       UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:[json objectForKey:@"friendlyErrors"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
       [alert show]; 
       alert = nil; 
      } 
      [MBProgressHUD hideHUDForView:self.view animated:YES]; 
     }); 


     [activitySpinner stopAnimating]; 
    }); 

我试过上面的,因为如果我在主线程上运行标签更改,它将不会改变,直到所有处理完成。

在我viewWillAppear我设置

HUD = [[MBProgressHUD alloc] initWithView:self.view]; 
    [self.view addSubview:HUD]; 
    HUD.delegate = self; 

它会显示连接,但不会显示处理或下载。

回答

0

实际测试此设备上后,我发现它确实确实显示处理和下载。它只是不显示在模拟器中。我想因为它使用了电脑处理器,所以它发生得很快。

1

由于Objective-C中是大小写敏感的,你有两个MBProgressHUD实例这里:

  • 您与[[MBProgressHUD alloc] initWithView:self.view];创建,不是添加到视图,但无法显示(它最初是隐藏的)
  • HUDhud您创建,添加到视图并立即与便捷构造[MBProgressHUD showHUDAddedTo:self.view animated:YES];

表明这实际上意味着HUD被隐藏在你的代码和你设置的任何属性更改不会显示(处理和下载),而hud是可见的,并显示您设置它(连接1)的唯一文本。

您的代码中存在一个额外的错误,它涉及在后台线程中创建视图(hud MBProgressHUD实例)。一般的经验法则是只修改主线程中的视图。设置hud的文本(以及其他一些属性)是一个值得注意的例外,因为MBProgressHUD在这里做了一些KVO欺骗,以确保您的线程安全。

此外,您应该意识到,即使您修复上述错误,您也会遇到将文本设置为“登录”(或显示警报)并立即隐藏HUD的场景,这意味着这段文字只能非常简短地看到。下载完成后,您可能不想隐藏HUD。 activitySpinner也有类似的问题。

所有的一切,你可以尝试这样的事情(从我的头顶书面):

[activitySpinner startAnimating]; 
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
hud.labelText = @"Connecting1"; 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    NSString *url = [NSString stringWithFormat:@"my URL", [dataObj.pListData objectForKey:@"API_BASE_URL"], userField.text, passwordField.text]; 
    NSLog(@"Login: %@",url); 
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]]; 

    NSError *error;   
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
    [hud setLabelText:@"Processing"]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if ([json objectForKey:@"authToken"] != nil) { 
      [hud setLabelText:@"Logging In"]; 
      NSLog(@"Found authtoken %@", [json objectForKey:@"authToken"]); 
      [dataObj setAuthToken:[json objectForKey:@"authToken"]]; 
      [dataObj setLocationId:[json objectForKey:@"c_id"]]; 

      [dataObj setStaffId:[[json objectForKey:@"staffOrRoomsId"] integerValue]]; 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
       [HUD setLabelText:@"Downloading"]; 
       // Download synchronosly here? 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        [MBProgressHUD hideHUDForView:self.view animated:YES]; 
        [activitySpinner stopAnimating]; 
       }); 
      }); 

      [self getAllData]; 
      [self performSegueWithIdentifier:@"segueToRootController" sender:self]; 
     } else { 
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:[json objectForKey:@"friendlyErrors"] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
      [alert show]; 
      alert = nil; 
      [MBProgressHUD hideHUDForView:self.view animated:YES]; 
      [activitySpinner stopAnimating]; 
     } 
    }); 
}); 
+0

谢谢,我会确保我没有创建任何线程。自从这篇文章我修改了代码,所以我会确定的。 – Bot 2012-04-23 18:29:36