2012-01-13 7 views
3

ウェブサービスリクエストでバイトデータを受け取り、iOSデバイスのファイルに書き込むことが必要な状況があります。これは、データのサイズが小さいために正常に動作しますNSFileHandle&iOSのファイルにAsynchを書き込む

stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent 

:私は、メソッドを使用して、私のiOSデバイス内のファイルにNSStreamを使用してデータを書き込むメモリ変数にし、最後に(データの最後まで)全てのデータを付加するために使用しましたしかし、問題は、私が大きなチャンク(カップルのMB)である可能性があるWebサービスを介してデータを受信して​​いる場合、私はそれを効率的にするために、ファイルに書き込むためにすべてをメモリに集めたくないということです。 NSFileHandleに切り替えると、小さいチャンクサイズのデータ​​を同じファイルに複数回書き込むことができます。今私の質問はこれを行うための最良のアプローチは何ですか?私は、NSFileHandleを使って、BACKGROUNDのファイルにどのように書き込むことができますか?私はこのようなコードを使用:

- (void) setUpAsynchronousContentSave:(NSData *) data { 

     NSString *newFilePath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/MyFile.xml"]; 
    if(![[NSFileManager defaultManager] fileExistsAtPath:newFilePath ]) { 
     [[NSFileManager defaultManager] createFileAtPath:newFilePath contents:nil attributes:nil]; 
    } 

    if(!fileHandle_writer) { 
     fileHandle_writer = [NSFileHandle fileHandleForWritingAtPath:newFilePath]; 
    } 
    [fileHandle_writer seekToEndOfFile]; 
    [fileHandle_writer writeData:data]; 

}

が、上記の方法に1-2メガビットのデータサイズを渡すと、私はそれがバックグラウンドで実行されているようにする必要がありますか?参考までに私はメインスレッドで書いています。

答えて

8

多分あなたはGrand Central Dispatchを試すことができます。

私はしばらく時間を費やしていましたが、私はそれを行う方法です。

Apple's documentによれば、私たちのプログラムは一度に1つのタスクしか実行する必要がない場合は、「シリアルディスパッチキュー」を作成する必要があります。まず、iVarとしてキューを宣言します。

dispatch_queue_t queue; 

データが発生すると

if(!queue) 
{ 
    queue = dispatch_queue_create("yourOwnQueueName", NULL); 
} 

を使用してinitViewDidLoadにシリアルディスパッチキューを作成し、あなたのメソッドを呼び出します。最後に

- (void) setUpAsynchronousContentSave:(NSData *) data { 

    NSString *newFilePath = [NSHomeDirectory() stringByAppendingPathComponent:@"/Documents/MyFile.xml"]; 
    NSFileManager *fileManager = [[NSFileManager alloc] init]; 
    if(![fileManager fileExistsAtPath:newFilePath ]) { 
     [fileManager createFileAtPath:newFilePath contents:nil attributes:nil]; 
    } 

    if(!fileHandle_writer) { 
     self.fileHandle_writer = [NSFileHandle fileHandleForWritingAtPath:newFilePath]; 
    } 
    dispatch_async(queue , 
       ^{ 
         // execute asynchronously 
         [fileHandle_writer seekToEndOfFile]; 
         [fileHandle_writer writeData:data]; 
        }); 
} 

は、私たちは、私がASIHttpでこれらのコードを組み合わせViewDidUnloaddealloc

if(queue) 
{ 
    dispatch_release(queue); 
} 

にキューを解放する必要があり、それが動作します。 お手伝いをしてください。

+0

うまくいきません!私が "setUpAsynchronousContentSave"を2回目に呼び出す場合、同じNSFileHandleを使って同じファイルにデータを追加するのは正しい方法ではないでしょう。 – Cam

+1

OK、私は私の答えを改善します。 – vampirewalk

+0

明日もう一度チェックします。ありがとうございました – Cam

関連する問題