`Self` reference in Swift instance member declaration

I have a struct setting that accepts a link as the only initialization parameter:

 internal struct NodeState: Equatable { weak var node: Node! = nil // ... init(node: Node) { self.node = node } } 

I want to instantiate NodeState as a member of the Node class, passing self in to set this weak link:

 public class Node: NSObject { internal var state = NodeState(node: self) // ... } 

... but I get this strange compilation error:

Cannot convert value of type 'NSObject → () → Node' to the expected argument type 'Node'

Am I not allowed to refer to self in a member declaration in Swift?

+5
source share
3 answers

In general, you cannot refer to self in a member class declaration, but you can if you make the property lazy and initialize it with a closure. Changing the Node class to something like this should work:

 public class Node: NSObject { internal lazy var staticState: NodeState = { NodeState(node: self) }() } 

This works because the lazy property is not initialized until self is initialized. self must be fully initialized before it can be used.

+2
source

Am I not allowed to refer to self in a member declaration in Swift?

Grade. You cannot reference self (for example, method calls, passing yourself as a parameter) until the object is fully initialized.

In this case, you can use a lazy var, which will work as it cannot be accessed until the object is initialized. Here is an example:

 public class Node: NSObject { internal lazy var staticState: NodeState = { return NodeState(node: self) }() } 
+2
source

Self link in close?

 public class Node: NSObject { lazy var staticState: () -> (NodeState) = { [unowned self] in return NodeState(node: self) } } 

I clearly decorate self as unowned in closure to prevent a save cycle.

+1
source

Source: https://habr.com/ru/post/1247988/


All Articles