1

確定進行状況バーを使用して長い計算を完了しようとしています。これは、以下のコードで正常に機能しています。ただし、 を呼び出すメソッドでは、オブジェクトの更新が完了する前scanにすぐに移動します。ディスパッチ キューが終了するのを待つためのさまざまな方法をすべて試しましたが、いずれも UI がハングしてしまいます。コールバックを使用する必要がありますか? このソリューションを調べましたが、すべての引数を渡し、変数を前後に返す方法がわかりません。 scoreWithEquationscanStoredLibrary

-(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]];
}

と は別の場所で別々に呼び出されるため、別々のメソッドとして 保持scanしたいと思います。scoreWithEquation

4

1 に答える 1

3

dispatch_async を使用すると、ディスパッチされたブロックは現在のスレッドをブロックせず、実行はすぐに続行されます。

あなたの場合、スキャンを呼び出すと、いくつかのことを行ってから、dispatch_async を呼び出して他のことを行います。この実行ループではディスパッチ ブロック内のすべてが実行されず、[self.storedLibrary scan] が返されるため、scoreWithequation がすぐに実行されます。

現在のスレッド (dispatch 呼び出しが実行されるスレッド) をブロックしたい場合は、dispatch_sync を使用する必要があります。

スキャン後に scoreWithequation を実行する場合は、serial_queue を作成し、dispatch_async を両方スキャンしてから、scoreWithequation をカスタム serial_queue に送信できます。そうすることで、実行は現在のスレッドをブロックせず、順番に実行されます。

「シリアル ディスパッチ キューの作成」をチェックします ( http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html )

または、scoreWithequation をコールバックとして実行するための完了ブロックを保持することも可能です。

于 2013-05-04T21:21:36.513 に答える