获取内存泄漏 - NSData 转换
Getting Memory Leakage - NSData conversion
我的 iPhone 4 在以下情况下收到内存压力警告:
我需要将图像上传到服务器并使用 Amazon s3。我正在使用以下代码将我选择的图像转换为 NSMutableData
:
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef)@{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: [NSNumber numberWithDouble: maxSize],
(id)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithDouble:compressionQuality]};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, options); // Create scaled image
CFStringRef UTI = kUTTypeJPEG;
NSMutableData *destData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, UTI, 1, NULL);
if (!destination) {
NSLog(@"Failed to create image destination");
}
CGImageDestinationAddImage(destination, thumbnail,( __bridge CFDictionaryRef)metadata); // copy all metadata in source to destination
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to create data from image destination");
}
if (!destination) CFRelease(destination);
CFRelease(source);
CFRelease(thumbnail);
return [destData copy];
为什么我在循环执行此操作时在第 24 个图像后收到内存警告?
由于您是将此图像作为一个整体加载到内存中,因此它的获取内存有问题。通常我会将图像保存到文档目录,然后使用图像的路径通过多部分上传图像。
那只会将图像加载为多部分,因此内存问题不会成为问题。我不知道这是否适用于您正在做的事情。
请告诉我。
这段代码有漏洞。
具体来说,您有一行内容为:
if (!destination) CFRelease(destination);
只有当它是 NULL
时才会释放它,这与您的意图相反:
if (destination) CFRelease(destination);
顺便说一句,如果你按shift+command+B,Xcode 将对您的代码执行静态分析。它会告诉您这个问题(以及代码中的其他一些问题)。它非常擅长发现这些问题。
我可能会建议如下:
- (NSData * _Nullable)processImageData:(NSData *)imageData maxSize:(double)maxSize compressionQuality:(double)compressionQuality metadata:(NSDictionary *)metadata {
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef)@{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: [NSNumber numberWithDouble: maxSize],
(id)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithDouble:compressionQuality]};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, options); // Create scaled image
CFRelease(source);
CFStringRef UTI = kUTTypeJPEG;
NSMutableData *destData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, UTI, 1, NULL);
if (!destination) {
NSLog(@"Failed to create image destination");
destData = nil;
} else {
CGImageDestinationAddImage(destination, thumbnail,(__bridge CFDictionaryRef)metadata); // copy all metadata in source to destination
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to create data from image destination");
destData = nil;
}
CFRelease(destination);
}
CFRelease(thumbnail);
return [destData copy];
}
我的 iPhone 4 在以下情况下收到内存压力警告:
我需要将图像上传到服务器并使用 Amazon s3。我正在使用以下代码将我选择的图像转换为 NSMutableData
:
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef)@{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: [NSNumber numberWithDouble: maxSize],
(id)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithDouble:compressionQuality]};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, options); // Create scaled image
CFStringRef UTI = kUTTypeJPEG;
NSMutableData *destData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, UTI, 1, NULL);
if (!destination) {
NSLog(@"Failed to create image destination");
}
CGImageDestinationAddImage(destination, thumbnail,( __bridge CFDictionaryRef)metadata); // copy all metadata in source to destination
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to create data from image destination");
}
if (!destination) CFRelease(destination);
CFRelease(source);
CFRelease(thumbnail);
return [destData copy];
为什么我在循环执行此操作时在第 24 个图像后收到内存警告?
由于您是将此图像作为一个整体加载到内存中,因此它的获取内存有问题。通常我会将图像保存到文档目录,然后使用图像的路径通过多部分上传图像。 那只会将图像加载为多部分,因此内存问题不会成为问题。我不知道这是否适用于您正在做的事情。
请告诉我。
这段代码有漏洞。
具体来说,您有一行内容为:
if (!destination) CFRelease(destination);
只有当它是 NULL
时才会释放它,这与您的意图相反:
if (destination) CFRelease(destination);
顺便说一句,如果你按shift+command+B,Xcode 将对您的代码执行静态分析。它会告诉您这个问题(以及代码中的其他一些问题)。它非常擅长发现这些问题。
我可能会建议如下:
- (NSData * _Nullable)processImageData:(NSData *)imageData maxSize:(double)maxSize compressionQuality:(double)compressionQuality metadata:(NSDictionary *)metadata {
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
CFDictionaryRef options = (__bridge CFDictionaryRef)@{(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
(id)kCGImageSourceThumbnailMaxPixelSize: [NSNumber numberWithDouble: maxSize],
(id)kCGImageDestinationLossyCompressionQuality: [NSNumber numberWithDouble:compressionQuality]};
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(source, 0, options); // Create scaled image
CFRelease(source);
CFStringRef UTI = kUTTypeJPEG;
NSMutableData *destData = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)destData, UTI, 1, NULL);
if (!destination) {
NSLog(@"Failed to create image destination");
destData = nil;
} else {
CGImageDestinationAddImage(destination, thumbnail,(__bridge CFDictionaryRef)metadata); // copy all metadata in source to destination
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"Failed to create data from image destination");
destData = nil;
}
CFRelease(destination);
}
CFRelease(thumbnail);
return [destData copy];
}