40472


例えば以下のようなコードのときに、parentとchildは循環参照してしまうのか。

[code]

    class Parent {
      let child = Child()
      let name = "parent"
    
      func didLoad() {
        child.callback = hoge
      }
    
      func hoge() {
        print(name)
      }
    }
    
    class Child {
      var callback: (() -> Void)?
    }
    
    let parent = Parent()
    parent.didLoad()
    
[/code]

もし、循環参照してしまう場合、対策として、 weak var
callbackと宣言するのが正しいのか。でもそうすると今度は無名のブロックが指定された場合即解放されてしまうと思うのだが、どっちでもうまくいく方法はあるか。


CC BY-SA 3.0
2017-12-21T17:12:53.793
40464
2019-06-29T09:04:18.983
2019-06-29T09:04:18.983
9008
427
question
swift swift3 メモリ管理 循環参照
swiftでblockにインスタンスメソッドを指定したときのselfは循環参照になるか


コード末尾の箇所を以下のようにかえてみれば実際に循環参照しているのか、いないのか確認できます。

[code]

    weak var weakParent:Parent? = nil 
    
    do {
        let parent = Parent()
        parent.didLoad()
        weakParent = parent
    }
    
    if let _ = weakParent {
        print("parentは解放されませんでした！！！")
    } else {
        print("parentは解放されました")  
    }
    
[/code]

答えを言ってしまうと、`child.callback = hoge` は循環参照になり、`parent`は解放されません。  
循環参照をさけるには横着せずに、

[code]

    child.callback = { [weak self] in self?.hoge() }
    
[/code]

と記述すればよいでしょう。  
`parent`の生存が確かなら `[unowned self]` でも構いません。


CC BY-SA 3.0
2017-12-22T05:15:40.167
40472
2017-12-22T05:15:40.167
23829
40464
answer