UIButton状态和选择器的进度

时间:2013-04-03 12:09:33

标签: ios objective-c uibutton ibaction uiprogressview

我在显示较长的主线程动作的进度时遇到了一些麻烦(需要在主线程中)。

按一个按钮调用该动作。

-(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更新进度。

我现在有两个问题:

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来电时出现死锁。

1 个答案:

答案 0 :(得分:2)

问题是您的主要线程被阻止了。这正是使用后台线程的原因,因为您不希望GUI冻结。

我不明白为什么解析CSV文件绝对的内容在主线程上。您必须在后台执行此操作(或使用冻结的GUI的糟糕用户体验)。

你有几个选择如何实际实现这样的东西。

  • 使用NSObject' s performSelectorInBackground:withObject:

    将解析代码放在一个单独的方法中,然后使用以下命令在后台线程上启动它:

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

    在该方法结束时,您在主线程上调用一些方法来通知它解析已经完成。

    [self performSelectorOnMainThread:@selector(parsingDone:) withObject:result waitUntilDone:NO];
    
  • 使用Grand Central Dispatch (GCD)使用块语法在后台运行一些代码。如果你习惯使用Objective-C和Cocoa API,那么也很简单,但语法和语义要复杂一些。

  • 使用NSOperationNSOperationQueue。可能会为您的目的带来一些开销。虽然您也可以通过调用addOperationWithBlock轻松地将新操作添加到队列中,而无需继承NSOperation