Являются ли недоступные объекты безопасными для сбора в течение какого-то времени после того, как они становятся недоступными? - PullRequest
3 голосов
/ 29 апреля 2011

Я храню некоторые объекты Obj-C в структуре данных C ++.Так как я работаю в сборщике мусора и мои объекты доступны только через структуру C ++, я вызываю CFRetain () для корня каждого объекта, добавленного в структуру, чтобы убедиться, что они не собираются преждевременно:1003 * Нужно ли это делать?Есть ли на самом деле какой-либо шанс, что GC сработает и соберет недоступные объекты во время метода, которым они становятся недоступными?Может ли сборщик мусора собираться в любое время или только в определенное время, например, в конце цикла выполнения?Не удалось найти соответствующую часть документации по этому вопросу.

Ответы [ 2 ]

1 голос
/ 09 мая 2011

Как указано в вашем коде, в котором все происходит в области действия doSomethingFancyWithObjects:, вам не нужна пара CFRetain/CFRelease, поскольку вы не удаляете объекты из array, который находится в стеке и поэтому укоренен.

Редактировать

ОК, я не правильно прочитал код - объекты копируются.

Во-первых, я бы поставил под сомнение необходимость копирования.Если вы изменяете объекты в списке, почему?Их выбрасывают в конце.

Во-вторых, у вас действительно есть состояние гонки.Сборщик мусора может попасть между list.push_back([obj copy]); и CFRetain(list.back());, и тогда указатель объекта в std::list будет зависать.Вы должны сделать что-то вроде:

NSObject* theCopy = [obj copy];
CFRetain(theCopy);
list.push_back(theCopy);
0 голосов
/ 29 апреля 2011

Я нашел некоторую информацию здесь:

Руководство по программированию сборки мусора

В стандартном приложении Какао автоматически намекает на подходящую точку в цикле событийэта коллекция может быть уместной.Сборщик затем инициирует сбор, если загрузка памяти превышает пороговое значение.Как правило, этого должно быть достаточно для обеспечения хорошей производительности.Однако иногда вы можете указать сборщику, что сбор может быть оправдан, например, после цикла, в котором вы создаете большое количество временных объектов.Вы можете сделать это, используя метод NSGarbageCollector collectIfNeeded.

Это, кажется, указывает на то, что сборщик мусора не будет магически запускаться в середине функций (или одновременно из другого потока!), Но только где-тов цикле событий.

Вы правы, однако, что в целом важно сохранять объекты в c ++, если вы не хотите, чтобы они были вымыты из-под вас, как указано в документе.:

Как правило, код C ++ должен оставаться неизменным: вы можете предполагать, что память выделяется из стандартной зоны malloc.Если вам нужно обеспечить долговечность объектов Objective-C, вы должны использовать CFRetain вместо retain.

EDIT

Упс, я обнаружил это подробнее освещающая часть эталона:

Коллектор управляется как запросом, так и запросом.Реализация Какао делает запросы в подходящее время.Вы также можете программно запросить рассмотрение цикла сборки мусора, и если порог памяти превышен, сбор запускается автоматически.

Сборщик работает в своем потоке в приложении.

Итак, как отмечает Джереми, сборщик мусора может работать в середине вашей функции, даже если ваша функция находится в главном потоке.

...