2012-05-17 12 views

Odpowiedz

2

Dla IBOutlets oznaczone jako silny nadal chce nil nich w viewDidUnload.

Dlaczego:

Po otrzymaniu powiadomienia o niskiej pamięci jakieś poglądy nie aktualnie widoczną może rozładować się (wywołanie viewDidUnload), aby zapisać w pamięci. Nielegając swoje sklepy, rezygnujesz z własności i pozwalasz im je wypuścić. Po ponownym załadowaniu widoku (gdy zostanie ponownie wyświetlony), gniazda zostaną ponownie ustawione i zostanie wywołana metoda viewDidLoad.

13

Głównym celem tego gniazda było nie tworzenie zombie, przecieków i dziwnych sytuacji, które mogłyby się zdarzyć, gdy subviews nie mają super widoku, a widok został usunięty z kontrolera widoku.

Teraz z najnowszej wersji Xcode jeśli przeciągnij element widok wewnątrz nagłówka lub w prywatnej deklaracji ustawia automatycznie gniazdka słaby (kierowania iOS> = 5), a także w sposobie viewDidUnload będzie pisać [self setYourOutlet:nil]; prawdopodobnie w tym przypadku nie jest konieczne, ale jest dobrą praktyką. Jeśli celujesz w niższe Iozy, potrzebujesz, ponieważ nie możesz użyć słabego odniesienia. Proponuję używać zawsze, ponieważ jest to dobry nawyk.

UPDATE

Chciałbym zakończyć odpowiedź, aby uniknąć nieporozumień (mówimy o iOS5 tylko) należy zwrócić uwagę, że IB wyznacza wylot słaby tylko wtedy, gdy są subviews z głównego widoku. Zazwyczaj dzieje się to w Xib zawierającym widok z kontrolera widoku.

Czasami może się zdarzyć, że trzeba zamienić dwa widoki na podstawie pewnych warunków w czasie wykonywania bez tworzenia ich programowo lub w innych bibliotekach. Na przykład masz główny widok będący własnością vc, a w tym samym xib tworzysz dwa inne widoki, które w tym momencie nie mają podglądu. Jeśli spróbujesz połączyć je za pomocą tej samej techniki, utworzony odnośnik będzie strong. W czasie wykonywania możesz teraz zamienić widoki, po prostu dodając lub usuwając z superwizji oczywiście powinieneś je zerwać w viewDidUnload.

+0

Dlaczego bierzesz pod uwagę następującą dobrą praktykę; "[self setYourOutlet: nil]; prawdopodobnie w tym przypadku nie jest konieczne, ale jest dobrą praktyką "? –

+0

@ Ríomhaire cóż, wyobraź sobie, że musisz obniżyć cel wdrożenia do 4.3, w tym przypadku będziesz musiał zmienić tylko słabe na unsafe_unretained – Andrea

+0

Nice, dzięki. –

11

Rozwiążę tutaj odpowiedź Andrei (przegłosuj go!), Ponieważ odpowiedź nie jest prosta, chyba że masz na myśli tylko elementy interfejsu użytkownika, w którym to przypadku powinny one być słabe (, wszystkie).

IBOutlety są takie, jakie je zdefiniujesz. Jeśli używasz:

@property (nonatomic, strong) IBOutlet UIView *someView;

powinieneś nil to podczas rozładunku nadrzędnego widok/okno.

Jeśli zrobić:

@property (nonatomic, weak) IBOutlet __weak UIView *someView;

Nie trzeba do zera zmiennej, ponieważ będzie to auto zero'ed.

To, w jaki sposób zerujesz, zależy wyłącznie od Ciebie. Przed ARC użyłem:

[someView_ release], someView_ = nil;

Teraz masz dwie opcje: albo użyć setter (utworzony zz @synthesize) lub ustawić podstawową ivar bezpośrednio. Wynik jest taki sam - w obu przypadkach kwalifikatory całego życia obiektu zwrócą uwagę na jego ostateczne wykorzystanie i zwolnią go.

Więc śmiało i to zrobić:

self.someView = nil

lub

@synthesize someView = someView_; 
... 
someView_ = nil; 
+4

+1 To jest właściwa odpowiedź. Musisz ustawić silne odniesienia do 'nil' w celu zwolnienia zasobów. Nie ma potrzeby ustawiania słabych odniesień do 'nil', ponieważ kompilator zrobi to za ciebie, jeśli zasób zostanie zwolniony. – Caleb

+0

Myślałem, że kompilator pod kontrolą ARC * mocne * właściwości również do zerowania? –

+0

To nie ma znaczenia - nie można go odczytać. Słabe właściwości mogą stać się zerowe w dowolnym momencie podczas wykonywania. Kiedy * w końcu * użyjesz obiektu o zasięgu lokalnym *, usuniesz go (powodując zwolnienie go przez kompilator), jeśli będziesz go nadal używał, możesz zaobserwować wartość zerową. Alternatywnie możesz pozwolić kompilatorowi zwolnić obiekt o zasięgu lokalnym, gdy jest poza zakresem, ale pozostawiając zakres oznacza użycie * ostateczne *, ponieważ nigdy nie obserwujesz wartości zerowej. Silne * właściwości * są ograniczone do twojej klasy, dlatego domniemane wydanie występuje w dealloc, po czym nie możesz uzyskać dostępu do członka. –

Powiązane problemy