słabe lub mocne dla IBOutlet i innych [duplikat]
To pytanie ma już odpowiedź tutaj:
- czy IBOutlets powinien być silny czy słaby pod łukiem? 11 odpowiedzi
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 jakoweak
.
@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ówweak
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?
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 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?
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?.
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.
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