When encrypting/decrypting large files, in our case, the memory usage spikes to 1.5G and app quickly crashes. We found the problem to be caused by RNCryptorEngine:addData:error creating 48K NSData objects that are not released fast enough. The fix is pretty simple: to add @autoreleaseblock to the two functions that use RNCryptorEngine:addData:error:
RNEncryptor:
- (void)addData:(NSData *)data
{
if (self.isFinished) {
return;
}
dispatch_async(self.queue, ^{
@autoreleasepool { // this fixes the memory issue
if (!self.haveWrittenHeader) {
NSData *header = [self header];
[self.outData setData:header];
if (self.hasHMAC) {
CCHmacUpdate(&self->_HMACContext, [header bytes], [header length]);
}
self.haveWrittenHeader = YES;
}
NSError *error = nil;
NSData *encryptedData = [self.engine addData:data error:&error];
if (!encryptedData) {
[self cleanupAndNotifyWithError:error];
}
if (self.hasHMAC) {
CCHmacUpdate(&self->_HMACContext, encryptedData.bytes, encryptedData.length);
}
[self.outData appendData:encryptedData];
dispatch_sync(self.responseQueue, ^{
self.handler(self, self.outData);
});
[self.outData setLength:0];
}
});
}
RNDecryptor:
- (void)decryptData:(NSData *)data
{
dispatch_async(self.queue, ^{
@autoreleasepool { // this fixes the memory issue
if (self.hasHMAC) {
CCHmacUpdate(&self->_HMACContext, data.bytes, data.length);
}
NSError *error = nil;
NSData *decryptedData = [self.engine addData:data error:&error];
if (!decryptedData) {
[self cleanupAndNotifyWithError:error];
return;
}
[self.outData appendData:decryptedData];
dispatch_sync(self.responseQueue, ^{
self.handler(self, self.outData);
});
[self.outData setLength:0];
}
});
}
When encrypting/decrypting large files, in our case, the memory usage spikes to 1.5G and app quickly crashes. We found the problem to be caused by RNCryptorEngine:addData:error creating 48K NSData objects that are not released fast enough. The fix is pretty simple: to add @autoreleaseblock to the two functions that use RNCryptorEngine:addData:error:
RNEncryptor:
RNDecryptor: