I have a struct
set up that accepts a reference as a single initialization parameter:
internal struct NodeState: Equatable {
weak var node: Node! = nil
// ...
init(node: Node) {
self.node = node
}
}
I want to instantiate a NodeState
as a member of the Node
class, passing self
in to set that weak reference:
public class Node: NSObject {
internal var state = NodeState(node: self)
// ...
}
…but I am getting this weird compile error:
Cannot convert value of type 'NSObject -> () -> Node' to expected argument type 'Node'
Am I not allowed to reference self
in a member declaration in Swift?
In general you can't reference self
in a member class declaration but you can if you make the property lazy and initialize it with a closure. Changing your Node
class to something like this should work:
public class Node: NSObject {
internal lazy var staticState: NodeState = { NodeState(node: self) }()
}
It works because the lazy property isn't initialized until after self
is initialized. self
has to be fully initialized before it can be used.
Am I not allowed to reference self in a member declaration in Swift?
Sort of. You can't reference self
(e.g. calling methods, passing self as a parameter) until the object is fully initialized.
You could use a lazy var in this case, which would work since it can't be accessed until the object is initialized. Here's an example:
public class Node: NSObject {
internal lazy var staticState: NodeState = {
return NodeState(node: self)
}()
}
Reference self in a closure?
public class Node: NSObject {
lazy var staticState: () -> (NodeState) = {
[unowned self] in
return NodeState(node: self)
}
}
I'm explicitly decorating self
as unowned
in the closure to prevent a retain cycle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With