2009-02-24 12 views
6

Zastanawiam się, jak autorelese działa na iPhone. Mimo to, po wysłaniu autorelease do obiektu , zostanie zagwarantowane, że zostanie zachowane do końca zakresu bloku, w którym wysłano autorelease. Czy to jest poprawne?Autorelease zakres

byłem inicjalizacji widok z NIB w applicationDidFinishLaunching jak poniżej:

(void)applicationDidFinishLaunching:(UIApplication *)application { 

    loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

i widok nie wykazują w ogóle, wszystko było na ekranie był UIWindow

Teraz kiedyś usunięto autorelease od początku inicjalizacji kontrolera, od tego momentu wszystko poszło gładko.

O co chodzi?

zdrowie, K.

Odpowiedz

13

Po wywołaniu autorelease, dajesz prawo własności obiektu do bieżącej puli autorelease. Pętla uruchamiania tworzy nową pulę autorelease, zanim wywoła zdarzenie (takie jak applicationDidFinishLaunching:) i niszczy tę pulę po zakończeniu zdarzenia.

Po przekazaniu własności puli LoginViewController do puli autoreasytów zostaje ona zwolniona zaraz po zwrocie applicationDidFinishLaunching:. Kiedy kontroler widoku zwolni się, usunie swój widok z podglądu (twoje okno w tym przypadku).

Twój delegat aplikacja powinna zachować prawo własności do LoginViewController i release go w dealloc metody App delegata (lub gdy skończysz z loginu i zostały przeniesione do innego widoku).

0

autoreleasepool jest oczyszczana na końcu runloop. Oznacza to, że tak długo, jak powołujesz się na metody i rzeczy, wciąż tam jest.

Nie widzę błędu w kodzie, ale okno zostało poprawnie zachowane w twoim przykładzie.

0

Od dodania swojej LoginViewController do puli autoreasytów jest ona zwalniana na końcu pętli uruchamiania. Kiedy tak się stanie, uwalnia także swój widok i usuwa go z widoku.

+0

Widok powinien zostać zatrzymany przez okno. (Nie mam dostępu do dokumentacji). –

+1

Ale gdy kontroler widoku jest zwolniony, usuwa widok, który zarządza z jego podglądu. –

+0

Dokładnie, co powiedział Don. –

4

Aby rozwinąć odpowiedź Dona, może być nieco mylące powiedzenie "przekazujesz własność obiektu do obecnej puli autorelease". To może być źle rozumiane, ponieważ oznacza, że ​​obiekt jest gwarantowany, że zostanie zniszczony, gdy pula autoreleaseu zostanie opróżniona. To nie jest poprawne (choć stanie się to w tym przypadku). Wysyłanie -autorelease żąda, aby pula autorelease wysłała wiadomość -release po jej opróżnieniu. Jeśli ten komunikat -release tworzy wartość retain = 0, to obiekt zostanie zniszczony.

Tak więc, aby zrobić to, co Don zaleca, należy utworzyć ivar, aby śledzić ten kontroler widoku. Jego wyjaśnienie, dlaczego widok znika, jest dokładnie słuszne; ale nie chcesz po prostu przeciekać kontrolera widoku. Chcesz go zatrzymać i uwolnić, kiedy skończysz.

@interface ... { 
    LoginViewController *_loginViewController; 
} 

@property (readwrite, retain) LoginViewController *loginViewController; 

@implementation ... 
@synthesize loginViewController = _loginViewController; 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    self.loginViewController = [[[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil] autorelease]; 

    [window addSubview: [loginViewController view]]; 
    [window makeKeyAndVisible]; 
} 

- (void)dealloc { 
    [_loginViewController release]; _loginViewController = nil; 
    [super dealloc]; 
}