Tak i nie. Skończyło się na zwolnieniu pamięci ciągu, ale „wyciekaniu” obiektu NSAutoreleasePool do pamięci przez użycie drenu zamiast zwolnienia, jeśli uruchomiono to w środowisku zbierania elementów bezużytecznych (bez zarządzania pamięcią). Ten „wyciek” po prostu sprawia, że wystąpienie NSAutoreleasePool jest „nieosiągalne”, jak każdy inny obiekt bez silnych wskaźników w GC, a obiekt zostałby wyczyszczony przy następnym uruchomieniu GC, co może być bezpośrednio po wywołaniu -drain
:
drenaż
W środowisku wyrzucania elementów bezużytecznych wyzwala wyrzucanie elementów bezużytecznych, jeśli pamięć przydzielona od ostatniej kolekcji jest większa niż bieżący próg; w przeciwnym razie zachowuje się jak zwolnienie. ... W środowisku ze śmieciami ta metoda ostatecznie wywołuje objc_collect_if_needed
.
W przeciwnym razie jest to podobne do tego, jak -release
zachowuje się pod nie-GC, tak. Jak powiedzieli inni, nie -release
działa w GC, więc jedynym sposobem, aby upewnić się, że pula działa poprawnie w GC, jest przejście -drain
, a -drain
pod non-GC działa dokładnie tak, jak -release
w przypadku innego niż GC i prawdopodobnie lepiej komunikuje swoją funkcjonalność, ponieważ dobrze.
Powinienem zwrócić uwagę, że twoje oświadczenie "wszystko wywołane z new, przydziel lub init" nie powinno zawierać "init" (ale powinno zawierać "copy"), ponieważ "init" nie alokuje pamięci, a jedynie ustawia obiekt (konstruktor moda). Jeśli otrzymałeś przydzielony obiekt, a twoja funkcja wywołałaby tylko init jako taką, nie zwolniłbyś jej:
- (void)func:(NSObject*)allocd_but_not_init
{
[allocd_but_not_init init];
}
To nie zużywa więcej pamięci niż ta, od której już zacząłeś (zakładając, że init nie tworzy instancji obiektów, ale i tak nie jesteś za nie odpowiedzialny).