2015-04-20 15 views
5

Mam bardzo ogólne pytanie o inicjalizację w Swift. W przeciwieństwie do Celu C, można teraz wywołać metodę init() bezpośrednio na deklaracji spoza moich funkcji: np.Gdzie zainicjować w Swift?

class ViewController: UIViewController { 
    let myView: UIView = UIView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myView.frame = getFrame() 
     myView.backgroundColor = UIColor.redColor() 
     self.view.addSubview(myView) 

    } 

    func getFrame() -> CGRect { 
     return CGRectMake(0, 0, 100, 100) 
    } 
} 

W celu C wykonałbym inicjalizację w mojej funkcji.

Ale co jeśli chcę wywołać inicjalizator z parametrami, które nie są jeszcze ustawione? np. Chcę init z ramą, która jest obliczana w func()

class ViewController: UIViewController { 

    //THIS IS NOT WOKRING 
    let myView: UIView = UIView(frame: getFrame()) 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myView.backgroundColor = UIColor.redColor() 
     self.view.addSubview(myView) 

    } 

    func getFrame() -> CGRect { 
     return CGRectMake(0, 0, 100, 100) 
    } 
} 

Nie chcę robić moje inicjacji w dwóch różnych miejscach w kodzie. Czy istnieje jakiś ogólny wzorzec dla inicjalizacji?

Odpowiedz

4

Twoje opcje inicjalizacji w szybkim są liczne. W bieżącym przykładzie nie można jeszcze użyć metody: getFrame(), ponieważ nie ma jeszcze odniesienia do self, ponieważ nie została zainicjowana operacja ViewController. Zamiast tego możesz użyć:

let myView: UIView = UIView(frame: CGRectMake(0, 0, 100, 100)) 

Ponieważ nie wymaga to odniesienia do siebie. Ewentualnie można lazy instancji, który będzie się uruchamiać po self jest dostępna (może być używany tylko z var nie let:

lazy var myView: UIView = { 
    return UIView(frame:self.getFrame()) 
}() 

Aby odpowiedzieć na to pytanie, przy użyciu klasy UIKit gdzie często nie mają kontroli nad ich instancji można dalej robić to samo było jak byłeś w Objective C i używać implicitly unwrapped ewentualne, (aby zapobiec konieczności korzystania z ! lub ? każdym razem instancji zmiennej, np

var myView: UIView! 

override func viewDidLoad(){ 
    super.viewDidLoad(); 

    myView = UIView(frame:getFrame()) 
} 

Thi s jednak nie działa ze stałymi let, ponieważ muszą być one przypisane natychmiast lub w konstruktorze obiektu. Mam nadzieję że to pomoże.

+0

Dziękuję za tę wspaniałą odpowiedź! Jak byś to zrobił? – Michael

+0

Nie ma twardych i szybkich reguł, ponieważ to naprawdę zależy od rodzaju klasy. Mówiąc, że zwykle deklaruję wszystkie stałe w linii (tzn. 'Let'), użyj' lazy var' dla wartości z domyślnymi wartościami, a następnie zainicjuj wszystkie zmienne tak wcześnie, jak to możliwe w cyklu życia klasy. Tak więc w klasach modelu (np. 'User' lub' Person') w init i 'viewDidLoad' of a' UIViewController'. – Bulwinkel