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

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

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

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

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

Мне нужно освободить peopleArray? Что насчет addressBook?

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

return [(NSArray*)peopleArray autorelease];

Обратите внимание, что это работает только для бесплатных мостовых классов. Мое понимание заключается в том, что довольно сложно создавать свои собственные бесплатные мостовые классы, а только примитивные (строковые, массивные и т.д.) Классы CF являются бесплатными мостами, поэтому такой подход не будет работать всегда. Наконец, если вы можете избежать использования autorelease (т.е. Вы можете сделать управление вашей памятью более явным), это, вероятно, всегда хорошо.

Ответ 3

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

См. этот fooobar.com/questions/166865/... для получения дополнительной информации.

Ответ 4

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

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

Ответ 5

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

return (__bridge_transfer NSArray*)peopleArray;

"__ bridge_transfer" перенесет право собственности на ARC, и поэтому вам не нужен дальнейший выпуск.