16

Jestem nowy w celu c i staram się zrozumieć zarządzanie pamięcią, aby to dobrze.Kiedy jest automatycznie wydany autoreleased obiekt?

Po przeczytaniu doskonałe
Memory Management Programming Guide for Cocoa przez apple moim jedynym problemem jest to, kiedy faktycznie autoreleased obiekt zostanie wydany w aplikacji iPhone/iPod. Moje zrozumienie jest na końcu pętli .. Ale co definiuje pętlę uruchamiania w aplikacji?

Tak więc zastanawiałem się, czy poniższy fragment kodu jest właściwy. Załóżmy obiekt

Czy ten kod jest prawidłowy?

Z tekstu apple i zrozumieć, że wrócił z NSString funkcjonalnie urządzonych jest ważny w zakresie functionB. Nie jestem pewien, czy jest on ważny w functionC oraz w viewDidLoad.

Dzięki!

Odpowiedz

17

Tak, twoje funkcje są prawidłowe i zwracaj obiekty, używając prawidłowych konwencji Cocoa do zachowania/wydania/autooddzielenia/kopiowania.

Aby odpowiedzieć na pytanie o to, co jest runloop w funkcji main() twojej aplikacji, wywołuje on UIApplicationMain(). Można sobie wyobrazić UIApplicationMain wygląda mniej więcej tak:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) { 
    UIApplication *app = /* create app using principalClassName */; 
    [app setDelegate:/* create delegate using delegateClassName */]; 
    while (![app shouldTerminate]) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     event = [app getNextEvent]; 
     [app dispatchEvent:event]; 
     [pool drain]; 
    } 
} 

że podczas pętli jest podobny do tego, co UIKit faktycznie robi, a każda podróż przez pętli while jest jak podróż przez runloop, gdzie bloki funkcja getNextEvent czeka na jakieś wydarzenie. Wszystkie twoje metody są zwykle wywoływane z poziomu czegoś takiego jak dispatchEvent :. Możesz spróbować ustawić punkt przerwania w jednej z twoich metod, takich jak IBAction i szukać w stosie wywołania debuggera na górze, aby zobaczyć nazwy metod UIKit obsługujących zdarzenia i runloop. Ponieważ każda twoja metoda jest wywoływana z tej pętli while, za każdym razem, gdy wywołujesz autorelease na obiekcie, ten obiekt jest dodawany do tej puli outter w pętli uruchamiania. Po zakończeniu wywoływania bieżącego zdarzenia pula zostanie opróżniona, a te obiekty zostaną ostatecznie wysłane.

Ostatnia uwaga. Może istnieć więcej niż jedna pula autoreleaseu, która nie zawsze znajduje się na końcu pętli zdarzeń. Czasami możesz rozdzielić dziesiątki tysięcy obiektów w trakcie jednej podróży od pętli zdarzeń. Gdy tak się stanie, możesz skonfigurować dodatkowe wewnętrzne puli automatycznej dystrybucji w swoich własnych metodach, aby zmniejszyć liczbę autoreleased obiektów w pulach autorelease. Pule automatycznej aktualizacji mogą się układać.

+0

Czy rozumiem poprawnie, że jeśli nie utworzyłem żadnej puli autorelease, wszystkie automatycznie wydane zmienne pozostaną w pamięci do momentu, aż aplikacja nie zostanie zamknięta? – Burjua

+0

W pewnym sensie, frameworki systemowe tworzą kilka puli autorelease dla ciebie u góry stosu głównego wątku w metodach takich jak UIApplicationMain(). Jeśli jednak uruchomisz własny wątek i nie utworzysz puli, to tak, obiekty te wyciekną. Metoda autorelease loguje się do konsoli w takim przypadku. –

+0

OK, dziękuję, ale to dziwne, normalną praktyką jest używanie konstruktorów, które zwracają autoreleased obiekty i nie zwalniają ich, ale tak naprawdę to jest to, że mają wyciek pamięci (pamięć jest alokowana aż do zamknięcia aplikacji). A może czegoś nie rozumiem? – Burjua

0

Nie ma nic złego w tym kodzie. Kompiluje się i działa zgodnie z oczekiwaniami.

Obiekt zwracany od functionA jest nadal ważny po powrocie, ponieważ jest przekazywany do następnego faceta (functionB), który teraz go obserwuje.

+3

"Przekazywany stos" prawdopodobnie nie jest najlepszym wyborem frazy, ponieważ sugeruje, że stos używa wartości zwracanych, co nie zawsze ma miejsce. –

Powiązane problemy