2013-04-03 69 views
0

我顯示一個較長的主線程動作的進度(需要在主線程中)有點麻煩。UIButton狀態和選擇器的進度

通過按下按鈕調用該操作。

-(void)getCSVExport:(id)sender{ 
    ... 
    NSString *filePath = [path stringByAppendingPathComponent:fileName]; 
    NSData *csvData = [NSData dataWithContentsOfFile:filePath]; 
    if (nil == csvData) { 
     _progressView.hidden = NO; 
     [self.view bringSubviewToFront:_progressView]; 
     _progressView.progress = 0; 
     csvData = [self generateCSVExportForMonth:_monthToExportInt]; 
     [csvData writeToFile:filePath atomically:YES]; 
     _progressView.hidden = YES; 
    } 
    ... 
} 

中的Funktion generateCSVExportForMonth:內我更新與_progressView.progress = newValue進展。

我現在有2個問題:

1)按調用getCSVExport:按鈕保持高亮顯示,直到通話結束按鈕時。 2)progressView從不顯示,更不用說更新自己了。

信息:根據設備的不同,呼叫需要0.5秒到2秒。

任何想法,我出錯了?

//編輯:新版本backgroundThread:

[self.view bringSubviewToFront:_progressView]; 
_progressView.progress = 0; 
[self performSelector:@selector(assignCSVData:) onThread:[NSThread new] withObject:csvData waitUntilDone:YES]; 
_progressView.hidden = YES; 

和時間昂貴的調用:

-(void)assignCSVData:(NSData*)data{ 
    data = [self generateCSVExportForMonth:_monthToExportInt]; 
} 

這導致於performSelector呼叫的僵局。

回答

2

問題是您的主線程被阻塞。這正是使用後臺線程來處理需要更長時間的事情的原因,因爲您不希望GUI凍結。

我不明白爲什麼像解析一個CSV文件絕對在主線程。你必須做它在後臺(或冷凍GUI的不好的用戶體驗生活)。

你有幾個選擇如何實際執行這樣的事情。

  • 使用NSObjectperformSelectorInBackground:withObject:

    把解析的代碼在一個單獨的方法,並使用啓動它在後臺線程:

    [self performSelectorInBackground:@selector(parseMethod) withObject:csvData]; 
    

    在該方法結束時,你就調用一些方法主線程通知它分析已經完成。

    [self performSelectorOnMainThread:@selector(parsingDone:) withObject:result waitUntilDone:NO]; 
    
  • 使用Grand Central Dispatch (GCD)運行在使用塊語法後臺一些代碼。而且很簡單,但稍微有點複雜的語法和語義明智的,如果你使用Objective-C和可可的API。

  • 使用NSOperationNSOperationQueue。可能是你的目的一點點的開銷。雖然你也可以很容易地通過調用addOperationWithBlock沒有子NSOperation添加一個新的操作隊列。

+0

我的問題是生成csv文件的方法訪問coredata。因爲過去曾發生過僵局,並希望避免這種僵局。讓用戶在應用程序的整個生命週期中等待最多2秒 - 報告將永遠不會重新創建,但存儲和重用 - 是我確保穩定性的計劃。另一種方式是,我需要確保應用程序停留在同一個地方(viewcontroller),直到生成報告爲止,因爲它將在那裏使用:/如果有一個聰明的做法,我會很高興以及:) –

+0

它是否總是依靠Cora數據對象?難道你不能只抓取你需要的對象,並把它們傳給後臺的解析器? – DrummerB

+0

報告需要5+(numberOfDaysOfMonth)提取,並不斷傳播函數執行。對象和屬性提取之間的提取差異很大。由於對結果進行繁瑣的排序,一次性提取所有內容會造成巨大的性能損失。 –