2016-10-05 32 views
6

Poniższy inicjalizacji obecnie produkuje ten błąd w wierszu, który wywołuje getEventCalendar:Inicjalizacja leniwe zmiennej instancji o wartości, która zależy od innych zmiennych instancji

Nie można użyć instancji członkowskiego „getEventCalendar” w nieruchomości inicjatora; inicjatory właściwości działają, zanim dostępne jest "samo".

Czy istnieje odpowiedni sposób do inicjowania zmiennej lazy instancji o wartości, która zależy od innych obiektów typu instance variables z self (nie tylko selfalone)? Mam np. próbował przekształcić getEventCalendar z metody w funkcję, ale to też nie pomaga.

class AbstractEventCalendarClient { 

    let eventStore: EKEventStore 
    let entityType: EKEntityType 

    lazy var eventCalendar = getEventCalendar() 

    init(eventStore: EKEventStore, entityType: EKEntityType) { 
    self.eventStore = eventStore 
    self.entityType = entityType 
    } 

    func getEventCalendar() -> EKCalendar? { 
    // ... 
    } 
} 
+2

pokrewne: http://stackoverflow.com/questions/38118429/swift-lazy-instantiating-using-self. –

Odpowiedz

4

Można użyć jednorazowe wykonane zamknięcie który przechwytuje właściwości self i użyć ich w realizacji (= pierwsze wykorzystanie nieruchomości lazy). Na przykład.

class Foo { 
    var foo: Int 
    var bar: Int 
    lazy var lazyFoobarSum: Int = { return self.foo + self.bar }() 

    init(foo: Int, bar: Int) { 
     self.foo = foo 
     self.bar = bar 
    } 
} 

let foo = Foo(foo: 2, bar: 3) 
foo.foo = 7 
print(foo.lazyFoobarSum) // 10 

W.r.t. do własnej próby: możesz, w ten sam sposób, skorzystać z funkcji pomocy (instancji) self w tym jednorazowym zamknięciu.

class Foo { 
    var foo: Int 
    var bar: Int 
    lazy var lazyFoobarSum: Int = { return self.getFooBarSum() }() 

    init(foo: Int, bar: Int) { 
     self.foo = foo 
     self.bar = bar 
    } 

    func getFooBarSum() -> Int { return foo + bar } 
} 

let foo = Foo(foo: 2, bar: 3) 
foo.foo = 7 
print(foo.lazyFoobarSum) // 10 
+0

Tak, sprytnie. Używam teraz tej wiersza verbatim: 'lazy var eventCalendar: EKCalendar? = {return self.getEventCalendar()}() '. – Drux

+0

@Drux: 'lazy var eventCalendar: EKCalendar? = self.getEventCalendar() 'powinno również działać, co zasugerowano w (teraz usuniętej) odpowiedzi z @Hamish. –

+0

@Drux Zauważ, że jak pokazał Hamish w swojej (teraz usuniętej) odpowiedzi, nie musisz owijać takiego wywołania metody pojedynczej instancji w samym zamknięciu, ale może po prostu użyć 'lazy var eventCalendar: EKCalendar? = self.getEventCalendar() 'bez zamknięcia. Metoda zamknięcia może być wygodna, jeśli chcesz dołączyć więcej logiki do leniwego wystąpienia 'eventCalender' (w twoim przypadku taka logika jest teraz zawarta w metodzie' getEventCalender'). – dfri

2

To mylący komunikat o błędzie (na którym możesz chcieć file a bug report). Problem jest tylko dziwactwem o właściwościach lazy - obecnie wymagają one jawnego użycia self w celu uzyskania dostępu do członków instancji, jak również wyraźnej adnotacji typu, która to robiła (co zostało wcześniej odnotowane w this Q&A).

Dlatego trzeba powiedzieć: (? Prawie duplikat)

lazy var eventCalendar: EKCalendar? = self.getEventCalendar()