2016-04-26 36 views
5

我有一個struct建立一個接受參考作爲單個初始化參數:參考`self`在夫特實例成員聲明

internal struct NodeState: Equatable { 
    weak var node: Node! = nil 
    // ... 

    init(node: Node) { 
     self.node = node 
    } 
} 

欲實例化一個NodeState作爲Node類的成員,並傳遞self中設置弱引用:

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

...但我得到這個奇怪的編譯錯誤:

Cannot convert value of type 'NSObject ->() -> Node' to expected argument type 'Node'

我不允許在Swift的成員聲明中引用self

+0

[初始化需要「自我」作爲參數斯威夫特特性]的可能的複製(http://stackoverflow.com/questions/25149248/initializing-swift-properties-that-require-self作爲一個參數) – jtbandes

+0

只是要注意,奇怪的編譯錯誤是由於[NSObject中的'self'方法](https://developer.apple.com/reference/objectivec/nsobjectprotocol/1418954-self)。在非ObjC類中,錯誤將僅僅是「使用解析標識符self'」。 – kennytm

回答

2

一般而言,您不能在成員類聲明中引用self,但如果您使屬性爲惰性並使用閉包對其進行初始化,則可以。改變你的Node類這樣的事情應該工作:

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

它的工作原理是因爲懶財產未初始化直到self初始化後。 self必須在可以使用前完全初始化。

+0

我得到完全相同的錯誤。 :(看起來有關類型推斷的事情被破壞了 – devios1

+0

它爲我編譯時沒有錯誤。你使用的是什麼版本的Xcode? –

+1

啊,我的壞,缺少staticState的顯式類型聲明。 – devios1

1

在閉包中引用self?

public class Node: NSObject { 

    lazy var staticState:() -> (NodeState) = { 
     [unowned self] in 
     return NodeState(node: self) 

    } 
} 

我明確地在封閉裝飾selfunowned防止保留週期。

+0

Just注意到什麼是錯誤的!這裏的懶惰變量被定義爲閉包類型,而不是'NodeState'實例類型(我不確定是否需要OP),因此,如果沒有[[unowned self]],它確實會創建一個保留如果你用一個自動執行的閉包(如接受的答案中所示)將該聲明更改爲一個'NodeState'實例類型,那麼不需要'[unowned self]',因爲Swift足夠聰明以避免保留循環case。 – Hamish

+0

對,這不是「錯誤」,它只是一個不同的實現(不是自動執行的閉包) – JAL

+0

當我說「錯誤」時,我的意思是我原來的評論有問題(關於'[無主自我]不是必需) - 不要質疑你的答案的正確性。 – Hamish

2

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

整理。您不能引用self(例如調用方法,將self作爲參數傳遞),直到對象完全初始化。

在這種情況下,你可以使用一個懶惰的變量,這將工作,因爲它只有在對象被初始化之後才能被訪問。這裏有一個例子:

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