Утечка памяти в CGImage - PullRequest
       18

Утечка памяти в CGImage

1 голос
/ 26 февраля 2010

У меня утечка памяти, я просто не знаю, как ее решить.

Это код утечки:

[newImg release];
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);
UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];
CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);
newImg = convertedImage;

Я изменяю информацию о пикселях, хранящуюся в данных, затем с помощью этого метода я создаю UIImage обратно из данных (который представляет собой массив без знака)

Инструменты xcode сообщают мне, что здесь есть утечки:

CGImageRef new_img = CGBitmapContextCreateImage(context);

А здесь:

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

хотя я выпускаю их обоих :( Может кто-нибудь сказать мне, как решить эту проблему?

Заранее спасибо ^ - ^

Ответы [ 4 ]

1 голос
/ 05 июня 2013

Почти наверняка вам не удастся выпустить newImg где-то еще в вашем коде. Возможно, вы не выпускаете его в -dealloc. Если это так, то инструменты будут помечать строку кода, выделившую память. Он не знает, когда вы должны или не должны были отпустить; он просто знает, когда была выделена память и когда она была освобождена. Вам нужно будет проверить ваш код на предмет того, как вы управляете этим ivar.

Тем не менее, вы имеете прямой доступ к своим иварам, что плохо. Это # 1 причина проблем с памятью в ObjC. Используйте свойства и средства доступа (за исключением init и dealloc), и эти проблемы, как правило, исчезнут. (И конвертировать в ARC. Очень редко есть причина больше использовать ручной подсчет удержания, особенно на iOS. Тем не менее, даже с ARC, я рекомендую использовать аксессоры и не касаться ваших иваров напрямую.)

Также: не называйте свою собственность newImg. Префикс new имеет особое значение в ObjC (это означает, что возвращаемый объект должен иметь эффективный счет удержания +1). Это может вызвать проблемы с памятью и ложноположительные предупреждения. У него должно быть имя типа convertedImage или nextImage.

0 голосов
/ 03 сентября 2012

CGBitmapContextCreate не публикует предоставленные вами данные. Либо дайте ему значение NULL (в этом случае контекст будет управлять собственной резервной памятью), либо освободите его самостоятельно после освобождения контекста.

РЕДАКТИРОВАТЬ: здесь является соответствующей документацией.

0 голосов
/ 05 мая 2013

Мне кажется, что вы не выпускаете convertImage Попробуйте заменить эту строку

UIImage * convertedImage = [[UIImage alloc] initWithCGImage:
                             new_img];

с этим

UIImage * convertedImage = [[[UIImage alloc] initWithCGImage:
                             new_img] autorelease];

в вашем коде.

И если я вас правильно понимаю (основываясь на комментариях к вопросу), вы объявляете свойство newImg следующим образом:

@property (nonatomic, retain) UIImage* newImg; //or something like that

В этом случае синтезированный установщик этого свойства сохранит любой объект, который будет ему присвоен. И отпустите его, когда значение изменится. Таким образом, вы не несете ответственности за его освобождение, и вам следует удалить эту строку:

[newImg release];

Полагаю, лучшее, что вы можете сделать, это прочитать Расширенное руководство по программированию управления памятью . Это не слишком долго, и все же он предоставляет полный обзор основных соглашений, используемых в управлении памятью iOS.

А поскольку вы также работаете с объектами / функциями CoreFoundation, рассмотрите Руководство по программированию управления памятью для Core Foundation .

Надеюсь, это поможет:)

0 голосов
/ 26 февраля 2010

Редактировать: Оригинальное сообщение, похоже, не помогло, поэтому удаление и повторная публикация.

Попробуйте вместо этого:

//[newImg release]; DELETE THIS LINE
CGColorSpaceRef d_colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =  CGBitmapContextCreate(Data, width, 
                                              height, 
                                              8, 4*width, 
                                              d_colorSpace, 
                                              kCGImageAlphaNoneSkipFirst);
UIGraphicsPushContext(context);
CGImageRef new_img = CGBitmapContextCreateImage(context);

newImg = [UIImage imageWithCGIImage:new_img];

CGImageRelease(new_img);
CGContextRelease(context);
CGColorSpaceRelease(d_colorSpace);

Протестировал это, и он не протекает на моем конце.

...