使用依赖于其他实例变量的值初始化惰性实例变量

时间:2016-10-05 07:11:45

标签: swift swift3 lazy-evaluation

以下初始化当前在调用getEventCalendar

的行中产生此错误
  

无法使用实例成员' getEventCalendar'在财产内   初始化;属性初始化程序在“自我”之前运行是可用的。

是否有任何合适的方法来初始化lazy实例变量,其值取决于instance variables的其他对象类型self(而不仅仅是self {{3 })?我是例如尝试将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 个答案:

答案 0 :(得分:4)

您可以使用一次性执行的闭包来捕获self的属性,并在执行时使用这些(=首次使用lazy属性)。 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。对你自己的尝试:你可以用同样的方式在这个曾经执行过的闭包中使用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

答案 1 :(得分:2)

这是一个令人困惑的错误消息(您可能希望file a bug report打开)。问题只是lazy属性的一个怪癖 - 它们目前需要显式使用self才能访问实例成员,以及在执行此操作时显式类型注释(之前已在this Q&A)。

因此你需要说:

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