これは、 iOS の RNCryptor で大きなファイルを非同期に復号化するためのフォロー アップです。
この記事で説明されている方法を使用して、ダウンロードされた大きなファイル (60Mb) を非同期で復号化することができました。Calman の回答で修正されました。
基本的には次のようになります。
int blockSize = 32 * 1024;
NSInputStream *cryptedStream = [NSInputStream inputStreamWithFileAtPath:...];
NSOutputStream *decryptedStream = [NSOutputStream output...];
[cryptedStream open];
[decryptedStream open];
RNDecryptor *decryptor = [[RNDecryptor alloc] initWithPassword:@"blah" handler:^(RNCryptor *cryptor, NSData *data) {
NSLog("Decryptor recevied %d bytes", data.length);
[decryptedStream write:data.bytes maxLength:data.length];
if (cryptor.isFinished) {
[decryptedStream close];
// call my delegate that I'm finished with decrypting
}
}];
while (cryptedStream.hasBytesAvailable) {
uint8_t buf[blockSize];
NSUInteger bytesRead = [cryptedStream read:buf maxLength:blockSize];
NSData *data = [NSData dataWithBytes:buf length:bytesRead];
[decryptor addData:data];
NSLog("Sent %d bytes to decryptor", bytesRead);
}
[cryptedStream close];
[decryptor finish];
ただし、まだ問題に直面しています。データ全体が復号化される前にメモリに読み込まれます。「送信、受信、送信、受信、.. .」。
小さな (2Mb) ファイル、またはシミュレータ上の大きな (60Mb) ファイルの場合は問題ありません。しかし、実際の iPad1 ではメモリの制約によりクラッシュするため、明らかにこの手順を実稼働アプリに適用することはできません。
ループdispatch_async
でやみくもにデータを送信するのではなく、使用してデクリプターにデータを送信する必要があるように感じますが、完全に失われています。while
私はもう試した:
- の前に独自のキューを作成し、
while
使用するdispatch_async(myQueue, ^{ [decryptor addData:data]; });
while
同じですが、ループ内でコード全体をディスパッチしますwhile
同じですが、ループ全体をディスパッチします- 自分のキューの代わりに
RNCryptor
-providedを使用するresponseQueue
これら 4 つのバリアントの中では何も機能しません。
ディスパッチ キューについてはまだ完全には理解していません。ここに問題があると感じています。誰かがこれに光を当てることができれば幸いです。