Свойство CGImageRef сохранять или не сохранять - PullRequest
3 голосов
/ 28 ноября 2011

У меня есть вопрос о том, как обрабатывать CGImageRef как синтезированное свойство класса.Если я определяю CGImageRef с

@property (nonatomic, retain) CGImageRef image;

, то компилятор жалуется, что здесь нельзя использовать «retain».Если я опускаю сохранение, то я предполагаю, что вместо него используется «назначение», и мне нужно сделать сохранение самостоятельно, когда я устанавливаю свойство:

self.image = CGImageRetain ( cgimage );

, тогда я получаю предупреждение «Потенциальная утечка», когдаработает анализ.Могу ли я безопасно игнорировать это предупреждение?Или синтезирующий код в любом случае выполняет неявный CGRetain, даже если в определении свойства не указано «retain»?

Ответы [ 3 ]

8 голосов
/ 28 ноября 2011

Что вы хотите сделать, это добавить аннотацию к свойству, что тип действительно может быть сохранен.

Изменить объявление свойства на

@property (nonatomic, retain) CGImageRef image __attribute__((NSObject));

Обратите внимание, что это будет генерировать только геттеры и сеттеры для вас, сама переменная экземпляра не управляемая ARC. В частности, это означает, что вы должны освободить его в dealloc, и вам нужно использовать правильное сохранение и освобождение при назначении непосредственно переменной экземпляра.


Лучшим подходом может быть использование typedef:

typedef CGImageRef CGImageObject __attribute__((NSObject));
@property (nonatomic, retain) CGImageObject image;

В этом случае переменная экземпляра управляется ARC, поэтому вы должны не отменить ее в dealloc и прямые назначения переменной экземпляра также обрабатываются ARC.


Для справки см. Спецификацию , в частности , раздел 4.1.1 :

Применение __attribute__((NSObject)) к имуществу, которое не подлежит возврату тип указателя объекта имеет то же поведение, что и вне ARC: требует, чтобы тип свойства был своего рода указателем и разрешает использование модификаторов, отличных от assign. Эти модификаторы влияют только на синтезированный геттер и сеттер; прямой доступ к ивару (даже если синтезированный) по-прежнему имеют примитивную семантику, а значение в иваре не будет автоматически освобожден во время освобождения.

и секция 3 :

Указатель сохраняемого объекта (или «указатель сохраняемого объекта») представляет собой значение тип указателя сохраняемого объекта («сохраняемый тип»). Есть три виды сохраняемых типов указателей на объекты:

  • блок-указатели (сформированные путем применения символа объявления каретки (^) к тип функции)
  • Указатели объектов Objective C (id, Class, NSFoo* и т. Д.)
  • typedefs, отмеченные __attribute__((NSObject))
1 голос
/ 28 ноября 2011

Я не люблю инструктировать компилятор при компиляции. Я думаю, что это некрасиво. Я бы переопределил методы сам.

@interface MyClass : NSObject {
    CGImageRef _image;
}
@property (nonatomic, assign) CGImageRef image;
@end

@implementation MyClass
- (void)setImage:(CGImageRef)i {
    if(_image != i) {
        CGImageRelease(_image);
        _image = CGImageRetain(i);
    }
}

- (CGImageRef)image {
    return _image;
}
@end
0 голосов
/ 28 февраля 2018

Как насчет этого?

@property (nonatomic, setter=setImage:) CGImageRef image;

(void)setImage:(CGImageRef)image {
    if (_image != image) {
        CGImageRelease(_image);
        _image = CGImageRetain(image);
    }
}
...