Dispatch-Warteschlangen und asynchroner RNCryptor

Dies ist eine Fortsetzung vonEntschlüsseln Sie eine große Datei asynchron mit RNCryptor unter iOS

Ich habe es geschafft, eine große, heruntergeladene Datei (60 MB) mit der in diesem Beitrag beschriebenen Methode, die von Calman in seiner Antwort korrigiert wurde, asynchron zu entschlüsseln.

Im Grunde geht es so:

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

Ich habe jedoch immer noch ein Problem: Die gesamten Daten werden in den Speicher geladen, bevor sie entschlüsselt werden. Ich kann eine Reihe von "Gesendeten X-Bytes an Entschlüsseler" und danach dieselbe Reihe von "Entschlüsseler empfangenen X-Bytes" in der Konsole sehen, wenn ich "Gesendet, empfangen, gesendet, empfangen, ..." sehen möchte. ".

Dies ist in Ordnung für kleine (2 MB) Dateien oder für große (60 MB) Dateien im Simulator. aber auf einem echten iPad1 stürzt es aufgrund von Speicherbeschränkungen ab, so dass ich dieses Verfahren für meine Produktions-App offensichtlich nicht beibehalten kann.

Ich habe das Gefühl, dass ich die Daten mithilfe von an den Entschlüsseler senden mussdispatch_async anstatt es blindlings in die Post zu schickenwhile Schleife, aber ich bin völlig verloren. Ich habe es versucht:

Erstellen meiner eigenen Warteschlange vor demwhileund mitdispatch_async(myQueue, ^{ [decryptor addData:data]; });das gleiche, aber den gesamten Code innerhalb derwhile Schleifedas gleiche, aber das ganze versendenwhile SchleifemitRNCryptor-unter der VoraussetzungresponseQueue anstelle meiner eigenen Warteschlange

Nichts funktioniert unter diesen 4 Varianten.

Ich habe noch kein vollständiges Verständnis der Versandwarteschlangen. Ich fühle das Problem liegt hier. Ich wäre froh, wenn jemand Licht ins Dunkel bringen könnte.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage