2012-07-16 38 views
1

我一直試圖讓這個工作一天,現在我仍然失敗。我想在安裝應用程序時將大量文件從軟件包複製到我的應用程序的「文檔」文件夾中,但這會讓用戶長時間等待應用程序顯示啓動畫面。UiAlertView與UIProgressView在本地複製文件

所以我想我會做一個初始的UIAlertView與UIProgressView作爲子視圖,每次將文件複製到文檔文件夾時得到更新。但是,警報顯示和進度欄永遠不會更新。我的邏輯是:

  • 設置UIProgressView和UIAlertView作爲我的ViewController的實例變量。
  • 在ViewDidLoad中,顯示警報並設置代理
  • - (void)didPresentAlertView:(UIAlertView *)alertView中執行for循環,該循環複製文件並更新UI。代碼爲:

    - (void)didPresentAlertView:(UIAlertView *)alertView{ 
        NSString *src, *path; 
        src = // path to the Bundle folder where the docs are stored // 
        NSArray *docs = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:src error:nil]; 
    
        float total = (float)[docs count]; 
        float index = 1; 
    
        for (NSString *filename in docs){ 
         path = [src stringByAppendingPathComponent:filename]; 
         if ([[NSFileManager defaultManager]fileExistsAtPath:path]) { 
          ... // Copy files into documents folder 
          [self performSelectorOnMainThread:@selector(changeUI:) withObject:[NSNumber numberWithFloat:index/total] waitUntilDone:YES];     
          index++; 
         } 
        } 
    [alertView dismissWithClickedButtonIndex:-1 animated:YES]; 
    } 
    

而對於ChangeUI代碼

- (void) changeUI: (NSNumber*)value{ 
    NSLog(@"change ui %f", value.floatValue); 
    [progressBar setProgress:value.floatValue]; 
} 

然而,這只是更新從0到1的UI,儘管打印的NSLog所有的中間值。有人在這裏知道我做錯了什麼嗎?

在此先感謝。

+0

您是否嘗試過調用「 - (void)setProgress: – Stavash 2012-07-16 11:12:39

+0

是的,但如果iOS <5.0,它會崩潰,這對我不利。 – 2012-07-16 11:31:37

回答

2

問題是,你的循環是在主線程,因此UI沒有機會更新,直到最後。嘗試使用GCD在後臺線程上工作:

dispatch_async(DISPATCH_QUEUE_PRIORITY_DEFAULT,^
    { 
     NSString *src, *path; 
     src = // path to the Bundle folder where the docs are stored // 
     NSArray *docs = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:src error:nil]; 

     float total = (float)[docs count]; 
     float index = 1; 

     for (NSString *filename in docs){ 
      path = [src stringByAppendingPathComponent:filename]; 
      if ([[NSFileManager defaultManager]fileExistsAtPath:path]) { 
       ... // Copy files into documents folder 
       dispatch_async(dispatch_get_main_queue(), ^{ [self changeUI:[NSNumber numberWithFloat:index/total]]; }); 

       index++; 
      } 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ [alertView dismissWithClickedButtonIndex:-1 animated:YES]; }); 
    }); 
+1

這和調用'[self performSelectorInBackground:@selector(changeUI :) withObject:[NSNumber numberWithFloat:index/total]]'是一樣嗎? – 2012-07-16 11:48:27

+0

不,不是。在Apple的Dock中查看該方法的說明 - 您需要「正確設置」。未來的潮流是大中央調度和阻止 - 蘋果不鼓勵NSThreads,他們一直在WWDC上公開表態。上面的調度使用Apple已經正確設置的線程。 GCD和ARC已經在蘋果平臺上編程壯觀! – 2012-07-16 13:17:46

+0

好的,謝謝@David。我已經接受了答案,現在我需要查看文檔。 – 2012-07-16 13:20:30