1

我正在尝试使用确定的进度条完成长时间的计算。这适用于以下代码。但是,在调用 的方法中scan,它立即转到完成更新对象scoreWithEquation之前。我已经尝试了所有不同的方法来等待调度队列完成,但它们最终都会挂起 UI。我需要使用回调吗?我已经研究过这个解决方案,但我不明白如何来回传递所有参数和返回变量。 scanStoredLibrary

-(void) scan{
if (!_sheet){
    [NSBundle loadNibNamed: @"ProgressSheet" owner: self];
}
[NSApp beginSheet: _sheet
   modalForWindow: [[NSApp delegate]window]
    modalDelegate: self
   didEndSelector: NULL
      contextInfo: nil];

[_sheet makeKeyAndOrderFront:self];

[_progressBar setIndeterminate:YES];
[_progressBar setMinValue:0];
[_progressBar startAnimation:self];

__block NSMutableArray *tempTracks = [[NSMutableArray alloc]init];

//do stuff

dispatch_async(dispatch_get_global_queue(0, 0), ^{

        //do stuff
        [_progressBar setDoubleValue:0.f];
        [_progressBar setMaxValue:[listTracks count]];
        [_progressBar setIndeterminate:NO];

        for (iTunesTrack *listTrack in listTracks) {
            //do stuff to tempTracks
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [_progressBar incrementBy:1];
            }); 
        }
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        [_progressBar setIndeterminate:YES];
        [NSApp endSheet:self.sheet];
        [self.sheet orderOut:self];
        self.listTracks = tempTracks;
    });
});
}

下面是调用的代码scan

- (IBAction)evaluate:(id)sender {
        if (self.storedLibrary == nil){
            self.storedLibrary = [[StoredLibrary alloc] init];
            [self.storedLibrary scan];
        }
self.tableTracks = [self.storedLibrary scoreWithequation:[_scoringEquation stringValue]
                                               sortOrder:[_sortOrder titleOfSelectedItem]                                                                                                   
                                              trackLimit:[_trackLimit integerValue]];
}

我想保留scanscoreWithEquation作为单独的方法,因为它们在其他地方被单独调用。

4

1 回答 1

3

当您使用 dispatch_async 时,调度的块不会阻塞当前线程,并且会立即继续执行。

在您的情况下,当您调用 scan 时,您会做一些事情,然后调用 dispatch_async 来做其他事情。调度块中的所有内容都不会在此运行循环中执行,并且 [self.storedLibrary scan] 返回,因此 scoreWithequation 将立即执行。

如果你想阻塞当前线程(执行dispatch调用的线程)你需要使用dispatch_sync。

如果要在scan后执行scoreWithequation,可以创建一个serial_queue,dispatch_async既scan再scoreWithequation到自定义的serial_queue。这样做不会阻塞当前线程,它们将被连续执行。

检查“创建串行调度队列”(http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

或者保留一个完成块来执行 scoreWithequation 作为回调也是可能的。

于 2013-05-04T21:21:36.513 回答