Базовые объекты Foundation и сохранение / выпуск сообщений - PullRequest
2 голосов
/ 29 сентября 2011

Допустим, у нас есть несколько базовых базовых объектов, таких как CGColorRef, которые добавляются к NSArray следующим образом:

CGColorRef color = ...;
NSArray *array = [NSArray arrayWithObject:(id)color];

Поскольку массивы сохраняют свое содержимое, color получает сообщение retain (не CFRetain(), верно?). Что происходит в этом случае с точки зрения управления памятью?

1 Ответ

10 голосов
/ 29 сентября 2011

Из основных принципов проектирования Foundation :

Обратите внимание на пример, что функции и методы управления памятью также взаимозаменяемы - вы можете использовать CFRelease с объектом Какао и release и autorelease с объектом Core Foundation.

В нем конкретно не упоминается retain, но на практике это также работает, как и copy (различные классы CFFooCreateCopy) и description (CFCopyDescription). Последнее, как вы можете передать объекты CF в качестве значения для спецификации форматирования %@ при использовании NSLog и других функций и методов форматирования строки.

Результат тот же: retain делает то же самое, что CFRetain, release делает то же самое, что CFRelease и т. Д.

Несколько вещей, о которых следует знать:

  • До iOS 7 и OS X 10.9 не было функции, аналогичной CF-методу NSObject autorelease. (7 и 10.9 принесли функцию CFAutorelease.) Если вы не используете ARC, то, как упомянуто в приведенной выше документации, вы можете отправить autorelease объекту CF, и он работает так же, как в NSObject. .
  • Вы можете отправить сообщение на nil, но не можете вызывать функции CF на NULL (произойдет сбой). Кварц имеет некоторые специфичные для класса функции, такие как CGContextRetain / Release, которые включают проверку NULL; хотите ли вы их использовать или всегда делаете свои собственные NULL проверки, это вопрос стиля.
  • Функции сохранения и освобождения CF работают при сборке мусора, тогда как сообщения retain и release не являются операционными (как если бы они отправлялись на nil). Не имеет значения, если вы не работаете с приложением GC'd Mac, в этом случае вам нужно будет использовать CFRetain и CFRelease для объектов CF.
  • Аналогично, в ARC сообщения retain и release будут недопустимыми, а объекты CF не будут автоматически подсчитываться по ссылкам. Вам нужно будет использовать CFRetain и CFRelease для объектов CF.
  • Коллекции всегда поступают правильно, как задокументировано. Обычно это означает сильную ссылку. Вне GC это означает, что коллекция (массив, словарь и т. Д.) Будет сохранять и освобождать свои объекты, будь то автоматически (по присваиванию, если его код ARCified) или вручную (посредством явных сообщений retain и release).
...