2016-10-05 4 views
6

Следующая инициализация в настоящее время производит эту ошибку в строке, которая вызывает getEventCalendar:Инициализировать ленивым переменную экземпляра со значением, которое зависит от других переменных экземпляра

Невозможно использовать экземпляр элемента «getEventCalendar» в свойстве инициализаторе; Инициализаторы свойств запускаются до «Я».

Есть ли подходящий способ для инициализации переменной экземпляра lazy со значением, которое зависит от другого объекта типа instance variables из self (а не только selfalone)? Я, например. попытался превратить getEventCalendar из метода в функцию, но это тоже не помогает.

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

Связанный: http://stackoverflow.com/questions/38118429/swift-lazy-instantiating-using-self. –

ответ

4

Вы можете использовать один раз только выполняется замыкание, которое фиксирует свойства self и использовать их при выполнении (= первое использование lazy собственности). Например.

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. к вашей собственной попытке: вы можете таким же образом использовать функции помощи (экземпляра) self в этом только что выполненном закрытии.

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

Да, умный. Теперь я использую эту дословную строку: 'lazy var eventCalendar: EKCalendar? = {return self.getEventCalendar()}() '. – Drux

+0

@Drux: 'lazy var eventCalendar: EKCalendar? = self.getEventCalendar() 'также должен работать, что было предложено в (теперь удаленном) ответе от @Hamish. –

+0

@Drux Обратите внимание, что, как показал Хэмиш в своем (теперь удаленном) ответе, вам не нужно обматывать такой вызов метода одного экземпляра в самом закрытии, но может просто использовать 'lazy var eventCalendar: EKCalendar? = self.getEventCalendar() 'без закрытия. Метод закрытия может быть удобным, если вы хотите включить больше логики в ленивую инстанцировку «eventCalender» (в вашем случае такая логика теперь содержится в методе 'getEventCalender'). – dfri

2

Это заблуждение сообщение об ошибке (которое вы можете захотеть file a bug report на). Проблема заключается лишь в причуде lazy свойств - в настоящее время они требуют явного использования self для доступа к экземплярам экземпляра, а также при аннотации явного типа (что ранее было отмечено в this Q&A).

Поэтому вы должны сказать: (? Почти дублируют)

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