Когда выпустить UIImage? - PullRequest
       4

Когда выпустить UIImage?

5 голосов
/ 28 декабря 2010

Я использую следующий код для рисования подизображения

UIImage* subIm = getSubImage( large, rect );
[subIm drawInRect:self.bounds];

, где getSubImage определяется следующим образом

    UIImage* getSubImage(UIImage* uim, CGRect rc){
      CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
      UIImage*   sub = [UIImage imageWithCGImage:imref];
      CGImageRelease(imref);
        NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
      return sub;
   }//getSubImage

Является ли код правильным?

это безопасно для "CGImageRelease" imref?

Имеет ли подпункт "CGImageRetained" imref?

Должен ли я выпустить subIm (если я получу ошибку)?

Содержится ли subIm в пуле autorelease, и, если да, как мне это узнать?

В общем, можно ли проверить, содержится ли объект в пуле автоматического выпуска (для целей отладки)?

Ответы [ 4 ]

15 голосов
/ 28 декабря 2010

Не звонить -retainCount

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

Сохранение счета следует рассматривать только как дельты; если вы заставляете счет удержания увеличиваться, вы должны уменьшать его.

Дано:

UIImage* getSubImage(UIImage* uim, CGRect rc){
  CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
  UIImage*   sub = [UIImage imageWithCGImage:imref];
  CGImageRelease(imref);
    NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
  return sub;
}//getSubImage

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

get* - странный шаблон для использования в программировании Какао. Вы просто не видите так много.

Я бы предложил что-то вроде:

- (UIImage *) subImage: (UIImage *) anImage inRect: (CGRect) aRect
{
      CGImageRef imageRef  = CGImageCreateWithImageInRect(anImage.CGImage, aRect); 
      UIImage*   subImage = [UIImage imageWithCGImage: imageRef];
      CGImageRelease(imageRef);
      return subImage;
}
6 голосов
/ 28 декабря 2010

Существует соглашение об именовании для управления памятью. Все Коды какао следуют этому правилу:

Основные правила управления памятью

Я настоятельно рекомендую вам прочитать этот документ и следовать этому правилу. Правило именования также является частью Какао.

Из справочной документации:

Вам принадлежит любой созданный вами объект. Вы «Создать» объект, используя метод чье имя начинается с «alloc» или «Новый» или содержит «копию» (например, alloc, newObject или mutableCopy).

Вы должны отказаться от права собственности на объекты, которыми вы владеете, когда вы закончите с ними. Вы отказываетесь от владения объект, отправив ему релиз сообщение или сообщение об автозапуске (Авто-релиз обсуждается в более подробно в «Авто-выпуске»). В какао терминология, отказ от собственности поэтому объект, как правило, упоминается как «освобождение» объекта.

Существует аналогичное правило для функций языка Си Базовой платформы. Однако нет таких авто-релиз-подобных вещей. Вы должны уточнить все в вашей документации, если вы хотите сделать объект Objective-C с функциями C.

И это может быть полезно для вас: imageWithCGImage и memory

4 голосов
/ 28 декабря 2010

SubIm зарегистрирован в пуле AutoRelease, поскольку этот объект фактически создается методом класса imageWithCGImage и что правило заключается в том, что экземпляры, созданные методами класса, всегда должны возвращать автоматически выпущенные экземпляры.

Код правильный, хотя я не понимаю, почему вы используете синтаксис C вместо синтаксиса Obj-C для определения вашей функции

0 голосов
/ 28 декабря 2010
  CGImageRelease(imref);
    NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
  return sub;

Поскольку в вашем методе нет ключевого слова alloc, retain, copy ..., вы должны автоматически выпустить UIImage перед его возвратом. Но заводской метод UIImage уже сделал это для вас. Имейте в виду, что даже если вы автоматически выпускаете саб, количество сохраняемых импульсов по-прежнему составляет 1

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