Освобождение ссылок на основные объекты Фонда


Нужно ли освободить объекты Core Foundation для очистки памяти? И если да, то как?

Например, в коде:

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);

Нужно ли мне освободить peopleArray? А как насчет addressBook?

5 20

5 ответов:

Да, в CoreFoundation вы должны выпустить что-либо с Create или Copy в имени. Вы делаете это с помощью CFRelease (). В вашем случае вы должны освободить как массив, так и ссылки на адресную книгу.

Правиладля управления памятью в Core Foundation аналогичны правилам в Cocoa: если метод, возвращающий ссылку, содержит слова "create" или "copy", вы владеете ссылкой и должны вызвать CFRelease() по этой ссылке, чтобы отказаться от владения. В противном случае вы не владеете ссылкой и должны вызватьCFRetain, чтобы принять право собственности (обязательно требуя, чтобы последующий CFRelease отказался от этого нового права собственности). Эти правила взяты из руководства по программированию управления памятью для основного основания являются:

  • Если вы создаете объект (либо непосредственно или сделав копию еще один объект-см. раздел " Создание Правило"), вы владеете им.
  • Если вы получите объект откуда-то еще, вы делаете не владеть им. Если вы хотите предотвратить это будучи утилизированы, вы должны добавить себя как собственника (используя CFRetain).
  • Если вы являетесь владельцем объект, вы должны отказаться от собственности когда вы закончите его использовать (используя CFRelease).

В вашем примере, и addressBook, и peopleArray должны быть освобождены. Поскольку в Core Foundation нет эквивалента autorelease, Если вы возвращаете ссылку a из метода, верните массив без его освобождения. Вы должны (если только вы не злой) затем включить "create" в имя метода, чтобы указать вызывающему, что они теперь владеют ссылкой на возвращаемый объект. В этом случае CFArray является бесплатным мостом к NSCFArray, объекту Objective-C, который наследует от NSObject. Таким образом, вы можете бросить peopleArray в NSArray* и autorelease что, если вам нужно вернуть его из функции / метода:

return [(NSArray*)peopleArray autorelease];
Обратите внимание, что это работает только для бесплатных мостовых классов. Я понимаю, что довольно сложно сделать свои собственные бесплатные мостовые классы и только примитивные (string, array и т. д.) Классы CF являются бесплатными мостами, поэтому такой подход не всегда будет работать. Наконец, если вы можете избежать использования autorelease (то есть вы можете сделать управление памятью более явным), это, вероятно, всегда хорошо.

Еще один маленький момент, о котором никто еще не упоминал, некоторые классы CF имеют "бесплатный мост" со своим аналогом NS. CFString и NSString, CFArray и NSArray - это оба примера. Это актуально, поскольку вы можете просто использовать release с этими классами.

Смотрите этот другой вопрос StackOverflow для получения дополнительной информации.

Я бы предложил прочитать руководство Apple по управлению памятью Core Foundation для углубленного обсуждения этого вопроса. У них также есть аналогичное руководство по общему управлению памятью какао.

Чтобы освободить объект CF, необходимо вызвать функцию CFRelease.

Для дуги вы можете использовать.

return (__bridge_transfer NSArray*)peopleArray;

"__мост_передача" передаче собственности на дуге, а следовательно, вам не нужны никакие дополнительные соединения.