-4

ビデオの再生開始時にavplayerのスクリーンショットを作成しようとしているので、このコードをバックグラウンドで高速に実行する必要があるため、メインスレッドをブロックせず、他のコントロールが同時に高速で実行され、そのコードGCD形式を実行しようとすると、できません実行して、配列に追加した場所で停止するように助けてください(配列にUIImageオブジェクトを追加しています)...

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil)
        {
            queue = dispatch_queue_create("array", NULL);
            dispatch_sync(queue, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });
            });
        }
    }
}
dispatch_release(queue);

編集:

私はdispatch_group_async今このブロックを使用する必要があると思います..使用方法のガイドラインを教えてください:

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil) {
            dispatch_group_async(serial_group1, serial_dispatch_queue1, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];
            });
        }
    }
    dispatch_group_notify(serial_group1, serial_dispatch_queue1, ^{
        NSLog(@"task competed");
    });
}

今、私はこのブロックを使用していますが、上記の実行は論争の的となっていますdispatch_suspend(serial_dispatch_queue1);。その停止を使用すると、再びブロックの実行を開始する必要があり、使用する必要があるものをdispatch_resume(serial_dispatch_queue1);再度ロードしてみましたが、システムはクラッシュを示します

4

1 に答える 1

1

dispatch_release(queue);そこではしないでください、あなたが呼び出しているディスパッチキューはbackThreadに行くので、起こっていることは次のとおりです:-

コードブロックが実行される前にキューが解放されます。

あなたqueueは ivar のように見えるので、dealloc で解放します。残り、コードは問題ないようです..ブレークポイントを中に入れて、ブロックが実行されているかどうかを確認してください。

編集

キューを一時停止することで何を達成しようとしているのかわかりません。それを行う必要はありません。ブロックの実行が終了したかどうかを確認する必要はありません。ブロックが終了して を呼び出し、dispatch_asyncメイン キューを取得してそこから UI を更新します。

ここで、キューを作成するときに、メソッドで遅延して作成します。キューをヘッダー ファイルの ivar として取得します。

@interface YourFileController : UIViewController {
    dispatch_queue_t queue;
}

次に、メソッドで次のように変更します。

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil)
        {
            if (!queue)
                queue = dispatch_queue_create("array", DISPATCH_QUEUE_SERIAL);

            dispatch_sync(queue, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });
            });
        }
    }
}

:DISPATCH_QUEUE_SERIALシリアル キューを作成します。これは、送信されたすべてのブロックが先入れ先出しの順序でシリアルに実行されることを意味します。送信されたすべてのブロックが実行されると、キューはそのままになります;) ..別のブロックをそれに送信すると、ブロックが実行されます:D

これは 1 つのブロック全体を表します:-

[avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });
于 2013-02-13T12:11:07.230 に答える