2012-03-29 52 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