2010-05-05 17 views
9

Biorąc pod uwagę dwa scenariusze, który kod jest najlepszą praktyką i dlaczego?Autorelease vs. Release

autorelease

loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)] 
               autorelease]; 
self.navigationItem.rightBarButtonItem = loginButton; 

lub

Release

loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login" 
               style:UIBarButtonItemStylePlain 
               target:self 
               action:@selector(loginButtonClicked:)]; 
self.navigationItem.rightBarButtonItem = loginButton; 
[loginButton release]; 

Odpowiedz

8

Wydaje się, że piętno przed użyciem autorelease (tj wolą zwolnić w miarę możliwości), dlatego ja zwykle iść drugą trasą. Ale ponieważ nie ma tu pętli, zwolnienie teraz w stosunku do autorelowania później będzie miało dokładnie taki sam efekt (ponieważ inny obiekt zachował loginButton, nie będzie to dealloc() ed).

Ale powinienem zauważyć, że większość moich wycieków pamięci jest spowodowana przez zapomnienie o dodaniu linii wydawniczej, więc lepiej byłoby po prostu od razu zająć się autoreazą.

+3

Na słabym urządzeniu pamięciowym, takim jak iPhone, lepiej jest jawnie zwolnić, jeśli to możliwe. Ułatwia także debugowanie dziwnych błędów EXC_BAD_ACCESS, ponieważ jednoznaczne wydanie oznacza, że ​​kontrolujesz długość życia obiektu. –

+1

@Alex, w tym przypadku dosłownie nie robi różnicy - obiekt jest zatrzymywany natychmiast po utworzeniu. Wszystko, co się wydarzy, to liczba referencyjna zostanie zmniejszona o jeden ... kogo to obchodzi, jeśli stanie się to natychmiast lub później? –

+0

Nie ma znaczenia, tylko jeśli nigdy nie zmienisz self.navigationItem.rightBarButtonItem przed zwolnieniem puli autorelease. – JeremyP

14

Dla przykładu, to naprawdę nie ma znaczenia. Osobiście prawdopodobnie użyłbym pierwszego przypadku. Pozwoliłoby to później dodawać modyfikacje lub debugować kod, nie martwiąc się o przeniesienie linii [loginButton release].

+1

Wszelkie wyjaśnienie downvote? –

+2

Nie mam pojęcia, prawdopodobnie tylko ktoś, kto czuje się wystarczająco silnie, że autorelease jest jakoś zły we wszystkich przypadkach na iPhone. Daję ci +1, ponieważ faktycznie rozważasz sprawę, którą opublikował, a nie tylko wydawanie zbiorczego oświadczenia. A ponieważ czuję to samo, co ty. –

+0

Korzystanie z pierwszego przypadku powoduje awarię mojej aplikacji.'- [UIBarButtonItem isSystemItem]: wiadomość wysłana do deallocated instance 0x2095f2c0' –

3

W twoim przypadku wszystko będzie dobrze, jak mówi Carl. Dzieje się tak, ponieważ obiekt UIBarButtunItem pozostaje w pamięci, ponieważ jedno odniesienie do niego jest przechowywane w self.navigationItem (zakładając, że zadeklarowałeś tę właściwość z @property (retain).). Dlatego zwykła diatryba dotycząca korzystania z puli autoreleaseów, która przechowuje niepotrzebne obiekty w pamięci do końca bieżącej pętli zdarzeń, nie ma tu zastosowania.

1

Ponieważ navigationItem zachowuje go, dwa w końcu jest identyczne. Pod względem stylu, autorelease jest preferowany dla zwrotów z metod, które nie mówią alokacji lub kopiowania w ich nazwie, ale poza tym to zależy od ciebie. Jeśli obiekt nie został oddzielnie zachowany, zwolnienie uwolniłoby pamięć szybciej.

Kwestia kod stylu ustawiania odniesienie do zera po wydaniu jest powiązany pytanie.

2

Skoro jesteś na bardzo napięty budżet pamięci na iPhone, preferowany sposób powinny być przez wyraźnego zwolnienia. W ten sposób obiekty nie będą się trzymać, dopóki pula autorelease nie zostanie opróżniona podczas biegu, a ty będziesz w stanie utrzymać swój ślad pamięci tak mały, jak to tylko możliwe.

+2

Ta krytyka dotyczy tylko tymczasowych obiektów "jednorazowych", które nie przetrwają w zakresie, w którym zostały utworzone. Kiedy tworzysz obiekt, który jest przechowywany długoterminowo, robi to mniejszą różnicę, ponieważ obiekt nadal będzie istniał niezależnie od tego, czy go zwolnisz, czy automatycznie. W takich przypadkach jest to bardziej kwestia preferencji. –

0

Po wysłaniu wiadomości o nazwie -autorelease do obiektu, dodajesz ją do listy i otrzymasz komunikat -release po zwolnieniu puli autorelease. Celem -autorelease jest dostarczenie sposobu na zrównoważenie zachowywania i wydawania, gdy coś jeszcze może chcieć zwolnić obiekt, ale nie. W opisywanej sytuacji drugi przykład jest lepszy.

0

Choć w prezentowanym scenariuszu oba przypadki są identyczne, ale istnieje niewielka przewaga prędkości do korzystania uwalnianie (reference) nad autorelease.So gdy istnieją surowe wymagania eksploatacyjne iść z wydaniem

Powiązane problemy