Сохраненная основная собственность фонда - PullRequest
12 голосов
/ 14 февраля 2012

(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.

Теперь мой вопрос заключается в том, нужно ли по-прежнему явно устанавливать эти свойства в ноль в моем dealloc?

Ответы [ 2 ]

15 голосов
/ 01 марта 2012

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


Исходное сообщение:

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

Так что нет, вам не нужно явноноль их в Deloloc.Вы получите ARC-поведение по умолчанию для nilling / release автоматически.

1 голос
/ 01 сентября 2017

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

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

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

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

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

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

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

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

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

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

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

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

typedef __attribute__((NSObject)) CGImageRef MyImageRef;

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

@property (nonatomic, strong) MyImageRef loupeImage;

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

...