devios1
devios1

Reputation: 37985

Reference `self` in Swift instance member declaration

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?

Upvotes: 5

Views: 2102

Answers (3)

JAL
JAL

Reputation: 42449

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.

Upvotes: 1

Ben Kane
Ben Kane

Reputation: 10040

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)
    }()
}

Upvotes: 2

Aaron Rasmussen
Aaron Rasmussen

Reputation: 13316

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.

Upvotes: 4

Related Questions