The following initialization currently produces this error in the line that calls getEventCalendar
:
Cannot use instance member 'getEventCalendar' within property
initializer; property initializers run before 'self' is available.
Is there any suitable way for initializing the lazy
instance variable with a value that depends on other object-type instance variables
of self
(not just self
alone) ? I've e.g. tried turning getEventCalendar
from a method into a function, but this does not help either.
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? {
// ...
}
}
You can use a once-only executed closure which captures properties of self
and use these at execution (= first use of the lazy
property). E.g.
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. to your own attempt: you may, in the same way, make use of help (instance) functions of self
in this once-only executed closure.
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
It's a confusing error message (which you may well want to file a bug report on). The problem is just a quirk of lazy
properties – they currently require an explicit use of self
in order to access instance members, as well as an explicit type annotation when doing so (which has been previously noted in this Q&A).
Therefore you need to say:
lazy var eventCalendar: EKCalendar? = self.getEventCalendar()