В чем разница между отправкой -release или -drain в пул автозапуска?

Во многих Книгах и на многих сайтах я вижу «слив». Что ж, для пула с автоматическим выпуском это звучит круто. Но разве он делает что-нибудь кроме релиза? Я бы предположил, что -drain просто заставляет пул -выпускать все его объекты, не освобождая сам пул. Просто предположение.


person Thanks    schedule 28.04.2009    source источник


Ответы (3)


Обратите внимание, что комментарии к ответу oxigen о том, что -drain не выпускает NSAutoreleasePool, неверны. В документации для NSAutoreleasePool четко сказано, что -drain освобождает (и, таким образом, уничтожает) NSAutoreleasePool.

-drain - это замена использования -release для объектов NSAutoreleasePool, с той лишь разницей, что дает подсказку для системы сборки мусора.

person smorgan    schedule 28.04.2009
comment
Спасибо. Так что на iPhone OS лучше использовать -release, чем -drain? - person Thanks; 28.04.2009
comment
В среде без GC они такие же. За исключением редкого случая, когда вы по какой-то причине не хотели бы давать подсказку системе GC, если бы код когда-либо использовался в режиме GC, нет причин использовать выпуск вместо утечки в коде, ориентированном на 10.4+. - person smorgan; 28.04.2009
comment
Apple не знает заранее, будет ли кто-то делать свою программу целевой до версии 10.4, и в любом случае нет смысла давать подсказку системе GC непосредственно перед выходом, что делает выпуск в этом конкретном случае лучшим выбором. - person smorgan; 29.04.2009

Если в вашей системе есть сборщик мусора, то -drain отправьте сообщение (objc_collect_if_needed) для GC

Если у вас нет GC, то сток = релиз

person oxigen    schedule 28.04.2009
comment
Методы -retain и -drain не изменяют keepCount объекта NSAutoreleasePool Они отправляют сообщение о выпуске только всем объектам в пуле, я не знаю, как и когда объекты NSAutoreleasePool уничтожаются ((( - person oxigen; 28.04.2009
comment
Нет, слив действительно освобождает бассейн. Нет никакого волшебства, когда дело доходит до пулов с автоматическим выпуском и сохраненных счетчиков, они следуют тем же правилам, что и любой другой объект, за исключением того, что они не могут быть сохранены или автоматически выпущены (что в любом случае не имеет большого смысла). - person Marc Charbonneau; 28.04.2009
comment
Марк Шарбонно Но почему я могу написать: NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; [выпуск пула]; [выпуск пула]; [выпуск пула]; [выпуск пула]; ..... [выпуск пула]; И это работа. И даже после этого pool keepCount = 1 - person oxigen; 28.04.2009
comment
Этого не должно быть. На самом деле, ARP должен быть уничтожен после выпуска, верно? - person Thanks; 29.04.2009
comment
oxigen, в вашем примере после ваших выпусков не происходит выделения, поэтому вы, вероятно, просто взаимодействуете с неповрежденной, но теперь уже мусорной памятью уничтоженного объекта. Тот факт, что вызов уничтоженного объекта работает, не означает, что этот вызов действителен. Что касается keepCount, возвращающего 1, возможно, keepCount просто всегда возвращает 1 для NSAutoreleasePool, поскольку он имеет необычную семантику сохранения. Даже если были какие-то детали реализации, которые делали его немного дольше, поскольку в документации явно говорится, что он освобождается при сливе или освобождении, вы должны предполагать, что это так. - person smorgan; 29.04.2009

Oxigen прав, см. Документацию для метода drain of NSAutoreleasePool:

В среде с подсчетом ссылок отпускает и извлекает приемник; в среде со сборкой мусора запускает сборку мусора, если объем памяти, выделенный с момента последней сборки, превышает текущий порог.

person zoul    schedule 28.04.2009