imageWithCGImage и память - PullRequest
       17

imageWithCGImage и память

17 голосов
/ 10 сентября 2009

Если я использую [UIImage imageWithCGImage:], передавая CGImageRef, тогда я освобождаю CGImageRef или UIImage позаботится об этом сам, когда его освободят?

Документация не совсем понятна. Он говорит: «Этот метод не кэширует объект изображения.»

Первоначально я вызвал CGImageRelease на CGImageRef после передачи его на imageWithCGImage:, но это вызвало предупреждение malloc_error_break в симуляторе, утверждающее, что произошел двойной разряд.

Ответы [ 8 ]

8 голосов
/ 01 мая 2010

В соответствии с фундаментальным правилом управления памятью Какао , объект-владелец должен освободить объект-владелец, когда он больше не нужен. Другие объекты несут ответственность за принятие и освобождение собственности самостоятельно. Если UIImage нужен объект для сохранения, но он не сохраняет или не копирует его, это ошибка в реализации UIImage, о которой следует сообщать.

4 голосов
/ 15 марта 2010

У меня та же проблема в XCode 3.2.1 на Snow Leopard. У меня почти такой же код, как у Джейсона.

Я посмотрел пример кода iPhone, который использует imageWithCGImage, и они всегда выпускают CGImageRef, используя CGImageRelease после вызова imageWithCGImage.

Итак, это ошибка в симуляторе? Я всегда получаю предупреждение malloc_error_break на консоли, когда использую CGImageRelease.

2 голосов
/ 21 апреля 2011

Право собственности на UIImage около CGImage неясно. Кажется, не копируйте CGImage, но это не гарантируется документацией. Таким образом, мы должны справиться с этим сами.

Я использовал новый подкласс UIImage для решения этой проблемы. Просто сохраняя прохождение CGImage и освобождая его, когда dealloc.

Вот образец.

@interface  EonilImage : UIImage
{
    @private
    CGImageRef      sourceImage;
}
- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation;

@end



@implementation     EonilImage

- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
{
    self    =   [super initWithCGImage:imageRef scale:scale orientation:orientation];

    if (self) 
    {
        sourceImage =   imageRef;
        CGImageRetain(imageRef);
    }

    return  self;
}
- (void)dealloc
{
    CGImageRelease(sourceImage);
    [super dealloc];
}
@end

Поскольку CGImage, возвращаемое свойством -[UIImage CGImage], не гарантирует совпадения с CGImage, переданным в метод init, класс хранит CGImage отдельно.

0 голосов
/ 24 сентября 2016
"This method does not cache the image object."

Таким образом, UIImage становится владельцем, и поэтому вы не должны выпускать CGImageRef.

0 голосов
/ 26 января 2011

Не уверен, поможет ли это, но у меня была похожая проблема. Я прочитал ответы и затем сделал следующее, что, кажется, исправило это:

CGImageRef cgImage = [asset thumbnail];
    UIImage *thumbImage = [[UIImage imageWithCGImage:cgImage ]retain];
    UIImageView *thumbImageView = [[UIImageView alloc] initWithImage:thumbImage];
    CGImageRelease(cgImage);

Я использовал авто-релиз, как было предложено, но этого было недостаточно. Я добавил изображение в UIImageView, а затем выпустил cgImage.
Это не разбилось и освободилось красиво. Почему - я понятия не имею, но это сработало.

Кстати, миниатюра актива есть в библиотеке ALAsset, вам может понадобиться что-то еще.

0 голосов
/ 11 мая 2010

<> Не мое мнение. У меня такая же проблема. Согласно документации

UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];

imho сохраняет правильность всех ссылок. Если вы используете CGDataProvider, пожалуйста, посмотрите на CGDataProviderReleaseDataCallback и установите точку останова в вашем обратном вызове. Вы можете видеть, что он правильно вызывается после [отпускания] вашего изображения, и вы можете освободить () свой буфер данных изображения там.

0 голосов
/ 21 сентября 2009

Используете ли вы Xcode 3.1 на Snow Leopard? Я испытываю ту же проблему:

CGContextRef ctx = ...;
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
UIImage * newImage = [[UIImage imageWithCGImage:cgImage] retain];

CGImageRelease(cgImage); // this should be OK, but it now crashes in Simulator on SL

Я предполагаю, что обновление до Xcode 3.2 решит проблему.

0 голосов
/ 10 сентября 2009

Я согласен с вами - документация для этого API в лучшем случае запутана. Исходя из вашего опыта, я бы пришел к выводу, что вы несете ответственность за срок службы обоих объектов - UIImage и CGImageRef. Кроме того, вы должны убедиться, что срок службы CGImageRef не меньше, чем UIImage (по понятным причинам).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...