2016-06-21 63 views
0

我得到的内存压力警告为我的iPhone 4与以下情况: 我需要上传我的图像到服务器,并使用亚马逊s3。我将我的选择图像分成NSMutableData与下面的代码:获取内存泄漏 - NSData转换

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后的图像内存警告,当我在循环中执行呢?

+0

的iPhone4已经具有非常低的内存,是它在其他设备中发生的事情,是你打开使用其他技术来上传图片到服务器? –

+0

谢谢Saheb,是的,只在iPhone 4上面临这个问题。 bcoz我已经尝试过使用iPhone 6和iPhone 5s,并且图片数量可能超过50张图片。是否有可能通过内存级别修复 – vetrivel

回答

0

由于您将此图像作为一个整体加载到内存中,所以它会提取内存问题。通常我会将图像保存到Document目录,然后使用图像的PATH通过多部分上传图像。 这只会加载图像作为multipart因此内存问题不会是一个问题。我不知道这是否适用于你正在做的事情。

请让我知道。

+1

这是一个很好的建议,但它实际上并不回答被问到的问题。 – Droppy

2

此代码有泄漏。

具体来说,你有这样一行:

if (!destination) CFRelease(destination); 

这将释放它,只有当它是NULL,这是你究竟想要什么相反:

if (destination) CFRelease(destination); 

顺便说一句,如果按转换 + 命令 + 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]; 
} 
+1

记录失败但实际上不采取其他行动也会导致代码中的灾难。 – Droppy

+0

同意。至少他应该在错误时返回'nil'。请参阅修正后的答案中的代码片段,该代码片段正是如此(并修复了原始代码片段中的其他一些问题)。 – Rob

+0

我会建议添加“Intruments Leaks”以帮助找到内存泄漏。因为内存压力并不总是意味着泄漏,如果是这样的话,“Intruments Allocation”可能会有所帮助,因为我担心作者认为内存压力=>内存泄漏。 – Larme