Да и нет. В конечном итоге вы бы освободили строковую память, но «просочили» объект NSAutoreleasePool в память, используя слив вместо выпуска, если бы вы запускали это в среде со сборкой мусора (не управляемой памятью). Эта «утечка» просто делает экземпляр NSAutoreleasePool «недоступным», как и любой другой объект без сильных указателей в GC, и этот объект будет очищен при следующем запуске GC, что вполне может произойти сразу после вызова -drain
:
слив
В среде со сборкой мусора запускает сборку мусора, если объем памяти, выделенной с момента последней сборки, превышает текущий порог; в противном случае ведет себя как релиз. ... В среде со сборкой мусора этот метод в конечном итоге вызывает objc_collect_if_needed
.
В остальном это похоже на то, как -release
ведет себя без GC, да. Как утверждали другие, -release
это не работает под GC, поэтому единственный способ убедиться, что пул функционирует должным образом под GC, - это сквозной -drain
, а -drain
под не-GC работает точно так же, как и -release
под не-GC, и, возможно, передает свои функции более четко, как хорошо.
Я должен указать, что ваше утверждение «все, что вызывается с помощью new, alloc или init» не должно включать «init» (но должно включать «copy»), потому что «init» не выделяет память, а только устанавливает объект (конструктор мода). Если вы получили объект alloc'd, а ваша функция вызывала только init как таковую, вы бы не выпустили ее:
- (void)func:(NSObject*)allocd_but_not_init
{
[allocd_but_not_init init];
}
Это не потребляет больше памяти, чем вы уже начали (при условии, что init не создает экземпляры объектов, но вы в любом случае не несете ответственности за них).