Tworzę wyłącznie na iOS 5 przy użyciu ARC. Czy IBOutlet
s UIView
(s) i (podklasy) powinny być strong
lub weak
?
Następujące:
@property (nonatomic, weak) IBOutlet UIButton *button;
Pozbyłby się tego wszystkiego:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Czy są jakieś problemy? Szablony są używane, strong
podobnie jak automatycznie generowane właściwości tworzone podczas łączenia bezpośrednio z nagłówkiem z edytora „Interface Builder”, ale dlaczego? Ten UIViewController
już ma strong
odniesienie do jego, view
który zachowuje swoje widoki.
IBOutletCollection()
nie może byćweak
, w przeciwnym razie zwraca jakonil
.strong
Odpowiedzi:
Obecnie zalecaną najlepszą praktyką firmy Apple jest, aby IBOutlety były silne, chyba że słaba jest szczególnie potrzebna, aby uniknąć cyklu przechowywania. Jak wspomniano powyżej Johannes, zostało to skomentowane podczas sesji „Implementing UI Designs in Interface Builder” z WWDC 2015, gdzie inżynier Apple powiedział:
Zapytałem o to na Twitterze inżyniera z zespołu IB, który potwierdził, że domyślne powinno być silne, a dokumenty programistów są aktualizowane.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
źródło
OSTRZEŻENIE, ODPOWIEDZIALNA ODPOWIEDŹ : ta odpowiedź jest nieaktualna w rozumieniu WWDC 2015, aby uzyskać poprawną odpowiedź, patrz zaakceptowana odpowiedź (Daniel Hall) powyżej. Ta odpowiedź zostanie zapisana.
Podsumowane z biblioteki programistów :
źródło
Podczas gdy dokumentacja zaleca używanie
weak
właściwości do widoków podrzędnych, od iOS 6 wydaje się być dobrym rozwiązaniemstrong
(domyślny kwalifikator własności). Jest to spowodowane zmianą wUIViewController
tym, że widoki nie są już rozładowywane.To powiedziawszy, jestem rozdarty między używaniem
i
w iOS 6 i później:
Użycie
weak
wyraźnie oznacza, że kontroler nie chce mieć prawa do przycisku.Ale pominięcie
weak
nie boli w iOS 6 bez rozładowywania widoku i jest krótsze. Niektórzy mogą zauważyć, że jest to również szybsze, ale jeszcze nie spotkałem aplikacji, która jest zbyt wolna z powoduweak
IBOutlet
s.Nieużywanie
weak
może być postrzegane jako błąd.Konkluzja: Od iOS 6 nie możemy się już mylić, dopóki nie używamy odciążania widoku. Czas na imprezę. ;)
źródło
nil
ręcznie ustawić wszystkie swoje punkty sprzedaży .weak
jest nieco tańszy w ARM64: Dweak
właściwości lub__weak
zmienne instancji. Chciałem tylko zauważyć, że istnieje tutaj mniejszy potencjał błędu. Co doweak
bycia tańszym na arm64, nawet nie widziałem prawdziwego problemu z wydajnościąweak
IBOutlet
zs na armv7. :)strong
ma to również sens.strong
jest szkodliwy tylko wtedy, gdy używasz rozładowywania widoku - ale kto to robi obecnie? :)Nie widzę z tym żadnego problemu. Przed ARC zawsze robiłem moje IBOutlety
assign
, ponieważ są już zachowane przez ich superwizje. Jeśli jeweak
wykonasz, nie powinieneś ich zerować w viewDidUnload, jak zauważyłeś.Jedno zastrzeżenie: możesz obsługiwać iOS 4.xw projekcie ARC, ale jeśli tak, nie możesz go używać
weak
, więc musisz je zrobićassign
, w którym to przypadku nadal chcesz zerować odniesienie,viewDidUnload
aby uniknąć zwisający wskaźnik. Oto przykład wiszącego błędu wskaźnika, którego doświadczyłem:UIViewController ma UITextField dla kodu pocztowego. Używa CLLocationManager do odwrócenia geokodowania lokalizacji użytkownika i ustawienia kodu pocztowego. Oto wywołanie zwrotne delegata:
Odkryłem, że jeśli odrzuciłem ten widok we właściwym czasie i nie wprowadziłem zerowego self.zip
viewDidUnload
, wywołanie zwrotne dla delegata może zgłosić wyjątek złego dostępu do self.zip.text.źródło
weak
właściwości nie muszą być uzupełnianeviewDidUnload
. Ale dlaczego szablon Apple do tworzenia placówek zawiera[self setMySubview:nil]
?IBOutlet
powinien być silny, ze względu na wydajność. Zobacz temat Storyboard Reference, Strong IBOutlet, Scene Dock w iOS 9Jak sugeruje Xcode 7
strong
Jeśli oglądasz sesję 407 WWDC 2015 Implementowanie projektów interfejsu użytkownika w Konstruktorze interfejsów , sugeruje (transkrypcja z http://asciiwwdc.com/2015/sessions/407 )
źródło
W rozwoju iOS ładowanie NIB nieco różni się od rozwoju Maca.
W rozwoju Maca IBOutlet jest zwykle słabym odniesieniem: jeśli masz podklasę NSViewController, zachowany zostanie tylko widok najwyższego poziomu, a po zwolnieniu kontrolera wszystkie jego widoki podrzędne i ujścia zostaną automatycznie zwolnione.
UiViewController wykorzystuje kodowanie wartości klucza do ustawienia gniazd przy użyciu silnych referencji. Więc kiedy zwolnisz swój UIViewController, widok z góry zostanie automatycznie zwolniony, ale musisz także cofnąć przydział wszystkich jego gniazd w metodzie zwolnienia.
W tym poście z Big Nerd Ranch omawiają ten temat, a także wyjaśniają, dlaczego użycie silnej referencji w IBOutlet nie jest dobrym wyborem (nawet jeśli w tym przypadku jest zalecane przez Apple).
źródło
Jedną rzecz, na którą chciałbym tutaj zwrócić uwagę, a mianowicie, pomimo tego, co inżynierowie Apple stwierdzili w swoim własnym filmie WWDC 2015 tutaj:
https://developer.apple.com/videos/play/wwdc2015/407/
Apple ciągle zmienia zdanie na ten temat, co mówi nam, że nie ma jednej właściwej odpowiedzi na to pytanie. Aby pokazać, że nawet inżynierowie Apple są podzieleni na ten temat, spójrz na najnowszy przykładowy kod Apple, a zobaczysz, że niektórzy ludzie używają słabych, a niektórzy nie.
W tym przykładzie Apple Pay zastosowano słaby: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_switch
Podobnie jak w przypadku obrazu w obrazie: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFlayer
Podobnie jak przykład Listera: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Podobnie jak przykład z lokalizacją podstawową: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swlement
Podobnie jak widok kontrolera przykład podglądu: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5
Podobnie jak w przypadku przykładu HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Hift_Serv_Data_Widoku
Wszystkie są w pełni zaktualizowane dla iOS 9 i wszystkie używają słabych gniazd. Z tego dowiadujemy się, że A. Problem nie jest tak prosty, jak się wydaje. B. Apple wielokrotnie zmieniało zdanie, i C. Możesz używać wszystkiego, co cię uszczęśliwia :)
Specjalne podziękowania dla Paula Hudsona (autora www.hackingwithsift.com), który udzielił mi wyjaśnień i odniesień do tej odpowiedzi.
Mam nadzieję, że to trochę lepiej wyjaśnia ten temat!
Dbać.
źródło
Od WWDC 2015 odbywa się sesja dotycząca implementacji projektów interfejsu użytkownika w Konstruktorze interfejsów . Około 32 minuty mówi, że zawsze chcesz wzmocnić swoją
@IBOutlet
siłę .źródło
Bądź świadomy,
IBOutletCollection
powinien być@property (strong, nonatomic)
.źródło
copy
tak jak jestNSArray
?Wygląda na to, że coś się zmieniło przez lata, a teraz Apple zaleca stosowanie silnego w ogóle. Dowody na ich sesję WWDC znajdują się w sesji 407 - Implementacja projektów interfejsu użytkownika w interfejsie Konstruktora i rozpoczyna się o 32:30. Moja uwaga z tego, co mówi, brzmi (prawie, jeśli nie dokładnie, cytując go):
połączenia wyjściowe powinny być silne, szczególnie jeśli połączymy widok podrzędny lub ograniczenie, które nie zawsze jest zachowywane przez hierarchię widoków
słabe połączenie wylotowe może być potrzebne podczas tworzenia niestandardowych widoków, które zawierają odniesienia do czegoś, co zostało utworzone w hierarchii widoków i ogólnie nie jest zalecane
Na innych oddziałach powinno być teraz zawsze silne, o ile niektóre z naszego niestandardowego widoku nie tworzą cyklu przechowywania z niektórymi widokami w hierarchii widoków
EDYTOWAĆ :
Niektórzy mogą zadać pytanie. Czy utrzymywanie go z silnym odwołaniem nie tworzy cyklu przechowywania, ponieważ kontroler widoku głównego i widok właściciela zachowuje odniesienie do niego? Albo dlaczego to się stało? Myślę, że odpowiedź jest wcześniejsza w tym wykładzie, kiedy opisują, jak stalówki są tworzone z Xib. Istnieje oddzielna końcówka stworzona dla VC i dla widoku. Myślę, że to może być powód, dla którego zmieniają zalecenia. Byłoby jednak miło uzyskać głębsze wyjaśnienie od Apple.
źródło
Myślę, że najważniejszą informacją jest: Elementy w Xib są automatycznie wyświetlane w pod-widoku. Wywiady to NSArray. NSArray jest właścicielem jego elementów. itd. mają silne wskazówki. Więc w większości przypadków nie chcesz tworzyć kolejnego silnego wskaźnika (IBOutlet)
A dzięki ARC nie musisz nic robić
viewDidUnload
źródło