mirror of
https://github.com/zhigang1992/PINRemoteImage.git
synced 2026-01-12 22:49:34 +08:00
Fix runaway NSData (#205)
* Fix runaway NSData Previously we were generating all the frames of the GIF and dispatching to write the data to the disk. This presents a problem if the disk backs up though and it can end up with theoretically every frame in memory. Instead, generate a frame and write it one frame at a time. Slower, but prevents this runaway memory situation. * Early return on error, thans @rahul-malik & @timonus!
This commit is contained in:
@@ -380,34 +380,41 @@ ERROR;}) \
|
||||
});
|
||||
}
|
||||
|
||||
CGImageRef frameImage = CGImageSourceCreateImageAtIndex(imageSource, frameIdx, (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceShouldCache : (__bridge NSNumber *)kCFBooleanFalse});
|
||||
if (frameImage == nil) {
|
||||
NSError *frameImageError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorImageFrameError userInfo:nil];
|
||||
HANDLE_PROCESSING_ERROR(frameImageError);
|
||||
break;
|
||||
}
|
||||
|
||||
Float32 duration = durations[frameIdx];
|
||||
fileDuration += duration;
|
||||
NSData *frameData = (__bridge_transfer NSData *)CGDataProviderCopyData(CGImageGetDataProvider(frameImage));
|
||||
NSAssert(frameData.length == width * height * kPINAnimatedImageComponentsPerPixel, @"data should be width * height * 4 bytes");
|
||||
|
||||
dispatch_group_async(diskGroup, diskWriteQueue, ^{
|
||||
if (PROCESSING_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGImageRef frameImage = CGImageSourceCreateImageAtIndex(imageSource, frameIdx, (CFDictionaryRef)@{(__bridge NSString *)kCGImageSourceShouldCache : (__bridge NSNumber *)kCFBooleanFalse});
|
||||
if (frameImage == nil) {
|
||||
NSError *frameImageError = [NSError errorWithDomain:kPINAnimatedImageErrorDomain code:PINAnimatedImageErrorImageFrameError userInfo:nil];
|
||||
HANDLE_PROCESSING_ERROR(frameImageError);
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *frameData = (__bridge_transfer NSData *)CGDataProviderCopyData(CGImageGetDataProvider(frameImage));
|
||||
NSAssert(frameData.length == width * height * kPINAnimatedImageComponentsPerPixel, @"data should be width * height * 4 bytes");
|
||||
NSError *frameWriteError = [self writeFrameToFile:fileHandle duration:duration frameData:frameData];
|
||||
HANDLE_PROCESSING_ERROR(frameWriteError);
|
||||
|
||||
CGImageRelease(frameImage);
|
||||
});
|
||||
|
||||
CGImageRelease(frameImage);
|
||||
frameCountForFile++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
completion(NO, nil, PROCESSING_ERROR);
|
||||
}
|
||||
|
||||
CFRelease(imageSource);
|
||||
}
|
||||
|
||||
dispatch_group_wait(diskGroup, DISPATCH_TIME_FOREVER);
|
||||
if (imageSource) {
|
||||
CFRelease(imageSource);
|
||||
}
|
||||
|
||||
//close the file handle
|
||||
PINLog(@"closing last file: %@", fileHandle);
|
||||
|
||||
Reference in New Issue
Block a user