2016-10-05 70 views
6

以下初始化目前在调用getEventCalendar行产生这个错误:懒初始化实例变量与价值依赖于其它的实例变量

不能使用物业 初始化中的实例成员“getEventCalendar”;属性初始值设定项在'self'可用之前运行。

是否有与该依赖于其他对象类型selfinstance variables的值初始化所述lazy实例变量的任何适当的方式(不只是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请注意,正如Hamish在他的(现在已删除的)答案中显示的那样,您不需要在封闭本身中封装这样的单个实例方法调用,但可以简单地使用'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()