nigdy nie przegap postu

czy kiedykolwiek żałujesz, że Apple włączyło dodatkowy inicjator do klasy UIKit? Szybkie rozszerzenia ułatwiają dodawanie nowych inicjalizatorów do typów bez podklasowania. Moje szybkie notatki na temat dodawania nowego wygodnego inicjatora do klasy UIKit przy użyciu rozszerzenia Swift.

wyznaczony czy wygodny?

najpierw podsumowanie dwóch typów inicjatora:

wyznaczony inicjator jest głównym inicjatorem dla klasy. Musi w pełni zainicjalizować wszystkie właściwości wprowadzone przez swoją klasę przed wywołaniem inicjalizatora superklasy. Klasa może mieć więcej niż jeden wyznaczony inicjator.

inicjalizator wygody jest drugorzędnym inicjalizatorem, który musi wywołać wyznaczony inicjalizator tej samej klasy. Jest to przydatne, gdy chcesz podać wartości domyślne lub inną konfigurację niestandardową. Klasa nie wymaga wygodnych inicjalizatorów.

trzy reguły

mając to jasne, musisz pamiętać o trzech regułach dla wyznaczonych i wygodnych inicjalizatorów dla typów klas:

  • wyznaczony inicjator musi wywołać wyznaczony inicjator z natychmiastowej klasy nadrzędnej.
  • wygodny inicjator musi wywołać inny inicjator z tej samej klasy.
  • wygodny inicjator musi ostatecznie wywołać wyznaczony inicjator.

co to dla nas oznacza? Mówiąc prościej, nie dzwoń super z wygodnego inicjatora. Wywołaj inny inicjator (wygodny lub wyznaczony) z tej samej klasy.

praktyczny przykład

spróbujmy z praktycznym przykładem. Tworzenie i konfigurowanie widoku obrazu z obrazu w katalogu zasobów gotowego do użycia z Auto layoutem wymaga kilku linii kodu:

// Create the imagelet heartImage = UIImage(named: "Heart")// Now create the image view using the imagelet heartImageView = UIImageView(image: heartImage)// Configure the view remembering to disable// the autoresizing mask if we are using// Auto LayoutheartImageView.translatesAutoresizingMaskIntoConstraints = false// Sometime we must also override the default content modeheartImageView.contentMode = .scaleAspectFit// Finally add to the view hierarchyview.addSubview(heartImageView)

szybko się to nudzi i zawsze zapominam wyłączyć tłumaczenie maski automatycznej zmiany rozmiaru.

Tworzenie inicjatora wygody

stwórzmy nowy inicjator wygody UIImageView, który wykona dla nas konfigurację. Nasz inicjalizator przyjmie nazwę obrazu w katalogu zasobów i trybie zawartości. Ponieważ nie zawsze chcemy ustawić tryb zawartości, domyślnie ustawimy skalowanie do wypełnienia. Oto kod:

extension UIImageView { convenience init?(named name: String, contentMode: UIViewContentMode = .scaleToFill) { guard let image = UIImage(named: name) else { return nil } self.init(image: image) self.contentMode = contentMode translatesAutoresizingMaskIntoConstraints = false }}

niektóre punkty do odnotowania:

  • Jeśli parametr Nazwa obrazu jest nieprawidłowy, nasz inicjalizator nie powiedzie się i powinien zwrócić nil. Definiujesz nieudany inicjalizator ze znakiem zapytania po słowie kluczowym init(init?).
  • gdy mamy poprawny UIImage wywołujemy wyznaczony inicjalizator UIImageView, aby utworzyć widok obrazu.
  • możemy ustawić właściwości obiektu UIImageView tylko po wywołaniu wyznaczonego inicjalizatora.

przykładowe użycie

// Default contentModelet heart = UIImageView(named: "Heart")// Specifying a contentModelet star = UIImageView(named: "Star", contentMode: .scaleAspectFit)

zauważ, że failable initializer oznacza, że typ zwracany jest opcjonalny (UIImageView?) więc musimy go rozpakować przed dodaniem go do superview.

dostęp do właściwości przed inicjalizacją Self

ostatnia uwaga dotycząca tego, kiedy możesz uzyskać dostęp do self, aby zmodyfikować właściwości. Jeśli spróbujemy ustawić właściwość UIImageView przed wywołaniem self.init(image: UIImage?) otrzymamy błąd:

// Does not compileself.contentMode = contentModeself.init(image: image)// Use of 'self' in property access 'contentMode'// before self.init initializes self

jeśli pamiętasz, że wyznaczony inicjator musi w pełni zainicjalizować wszystkie właściwości swojej klasy, możesz zobaczyć, dlaczego nie jest to dozwolone. Nawet jeśli kompilator pozwolił nam to zrobić, wyznaczony inicjalizator nadpisze naszą wartość wartością domyślną.

Czytaj dalej

sekcje dotyczące inicjalizacji i rozszerzeń w Przewodniku po języku programowania Swift zawierają dużo więcej szczegółów:

  • Inicjalizacja
  • rozszerzenia

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.