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

Непрерывное свойство основного ядра

(Xcode 4.2, iOS 5, ARC)

У меня есть некоторые свойства объектов Core Foundation (/Graphics), которые должны владеть их объектами. Теперь в этих Apple docs я нашел это:

В OS X v10.6 и более поздних версиях вы можете использовать ключевое слово __attribute__, чтобы указать, что свойство Core Foundation следует рассматривать как Objective-C объект для управления памятью: @property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

К сожалению, я не мог найти никаких подробностей об этом. Я использую это:

@property (nonatomic, strong) __attribute__((NSObject)) CGImageRef loupeImage;

И, похоже, он работает так, как я ожидал. Он сохраняет объект при настройке свойства и освобождает его, когда я устанавливаю свойство в nil.

Теперь мой вопрос: мне все еще нужно явно устанавливать эти свойства в nil в моем dealloc?

4b9b3361

Ответ 1

Изменить: Моя предыдущая запись была неправильной. __attribute__((NSObject)) в свойстве только заставляет его сохранять/освобождать свойство при использовании аксессуаров свойств. Это не влияет на доступ к ivar, и, в частности, он не отменяет (или не выпускает) свойство в dealloc. Так что да, в вашем dealloc вам либо нужно сказать self.loupeImage = nil;, либо вам нужно сказать [_loupeImage release].


Оригинальное сообщение:

Если компилятор принимает ключевое слово strong, то он будет обрабатывать его правильно, сохраняя и освобождая, как ожидалось, и автоматически завершая в ARC. Вся идея __attribute__((NSObject)) заключается в том, что он сообщает компилятору относиться к этому объекту точно так, как если бы он был объектом obj-c, и так, что он делает.

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

Ответ 2

Теперь мой вопрос: мне все еще нужно явно устанавливать эти свойства ноль в моем dealloc?

Да, вы делаете, с объявлением, которое вы показали.

В разделе раздел объявления свойств спецификации ARC говорится:

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

(акцент на последней добавленной мной части)

Другими словами, применение __attribute__((NSObject)) и strong в свойстве с использованием типа Core Foundation делает работу с геттерами и сеттерами корректными, но это не приведет к тому, что ARC управляет базовой переменной экземпляра (поскольку тип переменной экземпляра все равно будет тип Core Foundation), и поэтому ARC не будет выпускать переменную экземпляра на dealloc, если она не равна нулю. При таком объявлении свойства вам нужно будет обмануть его в dealloc или вызвать утечку.

Однако, есть способ заставить ARC управлять самой переменной. Поскольку переменная имеет тип Core Foundation, вы можете сделать ее управляемой ARC-типом, обернув ее в typedef с помощью __attribute__((NSObject)).

Раздел указателей сохраняемых объектов спецификации ARC говорит:

Существует три типа сохраняемых типов указателей объектов:

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

(акцент на последнем добавленном мной элементе)

Итак, если вы делаете typedef следующим образом:

typedef __attribute__((NSObject)) CGImageRef MyImageRef;

и объявите свое свойство следующим образом:

@property (nonatomic, strong) MyImageRef loupeImage;

базовая переменная будет управляться ARC (потому что базовая переменная будет иметь тип typedef 'd, который является типом управляемого ARC), и вам не нужно будет использовать его в dealloc.