Подтвердить что ты не робот

ImageWithCGImage и память

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

Владение в 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 отдельно.

Ответ 5

Используете ли вы 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 устранит проблему.

Ответ 6

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

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

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

Ответ 7

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

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

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

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

Ответ 8

"This method does not cache the image object."

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