1

wwdc 2012のブロック、GCD、およびXPCを使用した非同期デザインパターンで説明されているように、ファイルストレージキューサブシステムを実装しようとしています。データをフォーマットし、結果をカスタム並行ストレージキューに渡すカスタム並行処理キューがあります。次に、ストレージキューは書き込み用のdispatch_io_tチャネルを作成し、ファイルを分割し(ファイルを分割しないと、大きなデータでメモリの問題が発生します)、dispatch_io_writeを使用して各チャンクに書き込みます。書き込みがエラーなしで完了することもありますが、多くの場合、チャンクのいずれかEFAULTまたはいずれかを取得しますEDESTADDRREQ

私の一般的なアプローチの概要は次のとおりです。

dispatch_async(processingQueue, ^{

// prepare dispatch data for storageQueue

dispatch_async(storageQueue, ^{

    dispatch_io_t writeChannel = dispatch_io_create_with_path(DISPATCH_IO_STREAM,
                                                              [pathString UTF8String],
                                                              O_RDWR|O_CREAT, // read-write, create if not exist
                                                              S_IRWXU|S_IRWXG|S_IRWXO, // set all permissions
                                                              storageQueue,
                                                              ^(int error) {

                                                              });

    __block size_t chunkSize = STORAGE_WRITE_CHUNK_SIZE;

    __block off_t currentOffset = 0;

    dispatch_io_set_high_water(writeChannel, chunkSize);

    for (currentOffset = 0; currentOffset < imageDataSize; currentOffset += chunkSize) {

        // is dispatch_barrier required?
        dispatch_data_t blockData = dispatch_data_create_subrange(dictData,
                                                                  currentOffset,
                                                                  MIN(imageDataSize - currentOffset,chunkSize));


        if (dispatch_data_get_size(blockData) > 0) {

            dispatch_io_write(writeChannel,
                              currentOffset,
                              blockData,
                              storageQueue,
                              ^(bool done, dispatch_data_t data, int error){

                              });

        } else {

            NSLog(@"Error chunking data for writing!!");
            break;

        }
    }

    dispatch_io_close(writeChannel,0);
});
});

シリアルキューの使用、dispatch_barrierブロックのラップ、フラグの変更を試みましたが、問題は解決しません-アドレスまたは宛先が間違っているためにdispatch_io channel頻繁にエラーが発生しますdispatch_io_write

以下に対するいくつかの回答が必要です。1。カスタム並行キュー
を使用してバッファリングされたファイルの書き込みを行うための推奨される方法は何ですか。 2.チャネルまたはキューを使用する必要がありますか?使用する場合は使用しますか? 3.そのようなシナリオで知っておくべきチャネルフラグはありますか?dispatch_io_write
dispatch_barrierdispatch_io_barrierdispatch_barrier_async

4

2 に答える 2

0

DISPATCH_IO_STREAM フラグを使用してランダム アクセスをサポートしないストリームベースのチャネルを作成する場合、オフセット値 (currentOffset) は無視され、データは現在のファイルの場所 (スニペットでは 0) に書き込まれます

于 2014-07-22T08:35:00.980 に答える
0

あなたのスニペットには明らかに間違っているものはありません。データを手動でチャンクして複数の書き込み操作を送信する必要はありません (dispatch IO は、これを内部でより効率的に実行しています)。また、これらの特定の IO エラーが以前に発生したことは聞いたことがありません。

問題を再現する実行可能なテストケースとともにバグ レポートを提出してください。

于 2013-01-24T02:42:32.593 に答える