问题
I have some classes that create a graph with "back pointers". I tried to make the back pointers unowned
(they'd create cycles otherwise) and initialize them in my init()
, but that creates problems with self
references. How am I supposed to get around this?
class Parent {
var child1:Child
var child2:Child
unowned var myOwner:Thing
init(myOwner:Thing) {
child1 = Child(parent: self) // Compiler errors here
child2 = Child(parent: self) // and here
self.myOwner = myOwner
}
}
class Child {
unowned var parent:Parent
init(parent:Parent) {
self.parent = parent
}
}
The error I get is
'self' used before all all stored properties are initialized
回答1:
You have that error because Swift enforces that all variables must have a value before you can use self
to avoid your instance not being fully initialised. In your case you have two options:
1. Mark child1
and child2
as implicitly unwrapped optionals:
class Parent {
var child1: Child!
var child2: Child!
unowned var myOwner:Thing
init(myOwner:Thing) {
// Note - myOwner is being set before the children.
self.myOwner = myOwner
child1 = Child(parent: self)
child2 = Child(parent: self)
}
}
This results in no errors because both child1
and child2
have a default value of nil
, which you are then changing in init
.
2. Use lazy
instantiation:
class Parent {
lazy var child1: Child = Child(parent: self)
lazy var child2: Child = Child(parent: self)
unowned var myOwner:Thing
init(myOwner:Thing) {
self.myOwner = myOwner
}
}
This results in no errors because a lazy
property's value is only calculated when it is first used, therefore self
is guaranteed to have been fully initialised.
Hope that helps.
来源:https://stackoverflow.com/questions/29932151/how-to-initialize-bidirectional-graph-in-swift