słabe lub mocne dla IBOutlet i innych [duplikat]

To pytanie ma już odpowiedź tutaj:

Zmieniłem projekt na ARC i nie rozumiem, czy muszę używać strong lub weak dla Iboutletów. Xcode zrobić tak: w interface builder, jeśli utworzyć UILabel na przykład i podłączyć go z edytora asystenta do mojego ViewController, to Utwórz to:

@property (nonatomic, strong) UILabel *aLabel;

Używa strong, zamiast tego czytałem tutorial na stronie RayWenderlich, który mówi tak:

Ale dla tych dwóch szczególnych właściwości mam inne plany. Zamiast strong, zadeklarujemy je jako weak.

@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;

Weak jest zalecaną relacją dla wszystkich wylot właściwości. Te obiekty widoku są już częścią widoku kontrolera widoku hierarchii i nie muszą być utrzymywane gdzie indziej. The big korzyść deklarowania swoich punktów weak jest to, że oszczędza ci czas na pisanie metoda viewDidUnload.

Obecnie nasz viewDidUnload wygląda tak:

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.tableView = nil;
    self.searchBar = nil;
    soundEffect = nil;
}

Możesz teraz uprościć to do:

- (void)viewDidUnload
{
    [super viewDidUnload];
    soundEffect = nil;
}

Więc użyj weak, zamiast strong, i usuń zestaw na nil w videDidUnload, zamiast Xcode użyj strong, i użyj self... = nil w viewDidUnload.

Moje pytanie brzmi: kiedy muszę używać strong, a kiedy weak? Chcę również użyć do deployment target iOS 4, więc kiedy muszę używać unsafe_unretain? Każdy może pomóc mi dobrze wyjaśnić za pomocą małego samouczka, gdy używasz strong, weak i unsafe_unretain Z ARC?

Author: nhahtdh, 2012-06-23

2 answers

A rule of thumb

jeśli rodzic ma odniesienie do obiektu potomnego, należy użyć odniesienia strong. Jeśli dziecko ma odniesienie do obiektu nadrzędnego, należy użyć odniesienia weak lub unsafe_unretained (jeśli pierwsze z nich nie jest dostępne). Typowy scenariusz jest wtedy, gdy masz do czynienia z delegatów. Na przykład UITableViewDelegate nie zachowuje klasy kontrolera, która zawiera widok tabeli.

Tutaj wpisz opis obrazka

Tutaj prosty schemat przedstawiający główne koncepcje.

Załóżmy, że pierwsze A, B I C są strong odniesieniami. W szczególności, C mA strong ref do swojego rodzica. Kiedy obj1 jest zwolniony (gdzieś), odniesienie A już nie istnieje, ale masz przeciek, ponieważ istnieje cykl między obj1 i obj2. Mówiąc w kategoriach Liczby zatrzymań (tylko dla celów wyjaśniania ), obj1 ma liczbę zatrzymań równą 2 (obj2 ma odniesienie do niej strong), podczas gdy obj2 ma liczbę zatrzymań równą 1. Jeśli obj1 jest zwolniony, jego liczba zatrzymań wynosi teraz 1 i jego dealloc metoda nie jest wywoływana. obj1 i obj2 nadal pozostają w pamięci, ale nikt nie ma do nich odniesienia: .

Na kontarze, jeśli tylko a i B są strong refs, A C jest zakwalifikowane jako weak wszystko jest w porządku. Nie masz przecieków. W rzeczywistości, gdy obj1 jest zwolniony, to również uwalnia obj2. Mówiąc w kategoriach Liczby zatrzymań, obj1 ma liczbę zatrzymań równą 1, obj2 ma liczbę zatrzymań równą 1. Jeśli obiekt1 jest zwolniony, jego liczba zatrzymań wynosi teraz 0 i wywołana jest jego metoda dealloc. obj1 i obj2 są usuwane z pamięć.

Prosta sugestia: zacznij myśleć w kategoriach grafu obiektowego, gdy masz do czynienia z łukiem.

Jeśli chodzi o pierwsze pytanie, oba rozwiązania są ważne, gdy masz do czynienia z XIBs. Ogólnie rzecz biorąc, odniesienia weak są używane, gdy masz do czynienia z cyklami pamięci. Jeśli chodzi o Pliki XIBs, jeśli używasz strong, musisz ustawić nil W viewDidUnload, ponieważ jeśli tego nie zrobisz, w warunkach niskiej pamięci możesz spowodować nieoczekiwane wycieki. Nie wypuszczasz ich w dealloc ponieważ ARC zrobi to za ty. weak zamiast tego nie wymaga tego leczenia, ponieważ gdy obiekt docelowy zostanie zniszczony, wartości te są ustawiane automatycznie jako nil. Żadnych zwisających wskaźników.

Jeśli jesteś zainteresowany, naprawdę proponuję przeczytać piątek-qa-2012-04-13-nib-zarządzanie pamięcią by Mike Ash.

Jeśli chodzi o drugie pytanie, jeśli chcesz obsługiwać iOS 4, zamiast weak musisz użyć unsafe_unretained.

Wewnątrz więc jest wiele pytań/odpowiedzi. Tutaj główne:

Jak zastąpić słabe referencje podczas korzystania z ARC i kierowania iOS 4.0?

Jakiego rodzaju nieszczelności automatyczne zliczanie referencji w Objective-C nie zapobiega lub nie minimalizuje?

Korzystanie z ARC, kwalifikatora lifetime assign i unsafe_unreted

Strong / weak / retain / unsafe_unreted / assign

Mam nadzieję, że to pomoże.

Update

Zgodnie z komentarzem shaunlim, począwszy od iOS 6 viewDidUnload metoda jest przestarzała. Tutaj naprawdę proponuję zobaczyć odpowiedź Roba: iOS 6-viewDidUnload migrate to didReceiveMemoryWarning?.

 69
Author: Lorenzo B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:16

Możesz użyć weak dla obiektów, które są podłączone przez IBOutlets do obiektów w IB, ponieważ w tym przypadku obiekty będą tam tak długo, jak będzie tam superview. Dzieje się tak dlatego, że superview ma silny wskaźnik do swoich podwizów.

Jeśli wskaźnik, który definiujesz jest jedynym wskaźnikiem do obiektu, powinieneś zadeklarować go jako silny.

Jeśli jesteś zarejestrowanym deweloperem, zdecydowanie polecam zapoznanie się z filmami z wwdc11 i WWDC12. Kolejny dobry resource to podcast programistyczny iOS ze Stanford.

 11
Author: dasdom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-20 15:25:24