2016-06-21 4 views
0

Я получаю предупреждение о давлении памяти для своего iPhone 4 со следующим сценарием: Мне нужно загрузить свое изображение на сервер и использовать Amazon 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

Спасибо, Сахеб, да, только на iPhone 4 перед этим стоит проблема. bcoz я пробовал с iPhone 6 и iPhone 5s также с количеством отсчетов изображений, вероятно, 50+ изображений, которые это происходит должным образом. Возможно ли исправление на уровне памяти – vetrivel

ответ

0

Как вы загружаете это изображение в памяти в целом, поэтому его проблема с памятью. Обычно я бы сохранил изображение в каталоге Document, а затем загрузил изображение с помощью multipart, используя PATH изображения. Это загрузило бы изображение как многостраничное, поэтому проблема с памятью не была бы проблемой. Я не знаю, применимо ли это к тому, что вы делаете.

Пожалуйста, дайте мне знать.

+1

Это хорошее предложение, однако на самом деле он не отвечает на заданный вопрос. – Droppy

2

Этот код имеет утечку.

В частности, у вас есть линия, которая говорит:

if (!destination) CFRelease(destination); 

Это освободит его, только если это NULL, который является противоположностью того, что то, что вы хотели:

if (destination) CFRelease(destination); 

Кстати , если вы нажмете shift + команда + 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

Согласовано. По крайней мере, он должен возвратить «нуль» при ошибке. См. Фрагмент кода в пересмотренном ответе, который делает именно это (и исправляет пару других проблем в исходном фрагменте кода). – Rob

+0

Я предлагаю добавить «Утеплительные узлы», чтобы также найти утечки памяти. Потому что давление памяти не всегда означает утечку, и если это так, то может помочь «Распределение узлов», потому что я боюсь, что автор думал, что давление памяти => утечка памяти. – Larme

Смежные вопросы