2010-05-19 12 views
14

Nie mam pewności co do schematów własności obiektów wymaganych w następujących przypadkach. Kiedy mój UIViewController przedstawia kontroler popover, arkusz akcji lub inny kontroler widoku jako modalny, czy muszę pozostać na zachowanym odwołaniu do tego kontrolera podrzędnego, dopóki nie zostanie on odrzucony?Wzór zachowania/zwolnienia dla kontrolerów UIPopoverController, UIActionSheet i modal view?

Innymi słowy, czy poniższe wiersze kodu skutecznie "przenoszą" własność, czy nie?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO]; 

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

Czy ktoś może wskazać mi wyraźną dokumentację na ten temat?

Odpowiedz

26

UIPopoverViewController ma nieco inne zarządzanie pamięcią/posiadanie. Przedstaw popover nie zachowuje pamięci, więc nie możesz przenieść własności twojego popviewcontroller do prezentowanego obiektu.

Aby uniknąć wycieku pamięci, trzeba przyjąć UIPopoverControllerDelegate i wdrożenie metody DidDismissPopOver następujące:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [popoverController release]; 
} 

ten sposób można bezpieczne Alloc i przedstawić popover:

-(void)showSearch:(id)sender { 
    SearchViewController *searchVC = [[SearchViewController alloc] init]; 
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC]; 
    popVC.delegate = self; 
    [popVC setPopoverContentSize:CGSizeMake(320, 100)]; 
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES]; 
    [searchVC release]; 
} 
+1

Uwaga: searchVC jest nieszczelny, jeśli robisz to w ten sposób. Dodaj autorelease. – steipete

+0

Tak, wyszukiwanieVC wyciekło. Zamiast autoreakcji będzie działać również proste wydanie. Dodaj to do ostatniej linii: '[searchVC release]; –

+1

Jako dokumentacja dla' popoverControllerDidDismissPopover: 'mówi: _" Popover kontroler nie wywołuje tej metody w odpowiedzi na programowe wywołania metody dismissPopoverAnimated: Jeśli programowo odrzuć popover, należy wykonać wszystkie akcje czyszczące natychmiast po wywołaniu metody dismissPopoverAnimated: "_. Więc jeśli użyjesz 'dismissPopoverAnimated:' będziesz również musiał wywołać wydanie po tym, w przeciwnym razie dostaniesz wyciek. – ivanzoid

1

Przedstawienie modalnego kontrolera widoku zachowuje kontroler UIViewController. Z dokumentacji tej nie wynika to jasno. Jednak ja testowałem go za pomocą następującego kodu ...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]); 
[self.navigationController presentModalViewController:self.setupViewController animated:YES]; 
NSLog(@"AFTER %d", [self.setupViewController retainCount]); 

self.setupViewController już zatrzymanego lokalnie, ale prezentując to wyjście następuje:

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1 
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3 

Więc to są prawdopodobnie zachowane w lokalna właściwość modalViewController, a także w hierarchii widoku. Odrzucenie go zrównoważy te.

Tak więc podstawą jest zachowanie go, jeśli chcesz kontrolować je bezpośrednio, ale nie musisz tego robić.

EDYCJA - Po prostu, aby być jasnym, wzór ma zawsze zachować obiekt, jeśli ustawisz się jako jego pełnomocnik. To dlatego, że powinieneś ustawić delegata na zero w swoim debiucie dla bezpieczeństwa. Praktycznie jednak kontroler modalny zawsze zostanie zwolniony przed zwolnieniem, więc nie jest to problemem. Zauważysz, że Apple łamie tę zasadę również w [UIView setAnimationDelegate:], która w rzeczywistości zachowuje delegata, który ustawiłeś.

+0

bym również dodać, że duża część przykładowego kodu Apple inicjuje UIViewController, przedstawia go modalnie, a następnie zwalnia. Sprawdź przykład AddMusic. – DougW

+0

Czy to samo dotyczy witryn internetowych i arkuszy akcji? –

+0

Tak, możesz zwolnić UIAlertView, a następnie zwolnić. Lub możesz go zatrzymać, jeśli chcesz coś z tym zrobić. Tak czy inaczej jest w porządku, po prostu upewnij się, że zachowujesz równowagę pomiędzy zachowaniem/wydaniami. – DougW

Powiązane problemy