0

親クラスと子クラスがあります。親には子への強い参照があり、子には親への所有されていない参照があります。親のdeinit中に、子にクリーンアップをしてもらいたいのですが、それには親の呼び​​出しが含まれます。

class ViewController: UIViewController
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        let parent = Parent()
    }
}

class Parent : NSObject
{
    override init()
    {
        super.init()

        child.doStuff()
    }

    deinit
    {
        child.doStuff()
    }

    lazy private var child : Child = Child(parent : self)
}

class Child : NSObject
{
    init(parent : NSObject)
    {
        self.parent = parent
    }

    func doStuff()
    {
        println(self.parent)
    }

    deinit
    {

    }

    private unowned var parent : NSObject
}

残念ながら、doStuff()親の deinit 中に呼び出すと、以下を使用するため、クラッシュが発生しますself.parent

libswiftCore.dylib`_swift_abortRetainUnowned:
    0x111e91740 <+0>:  leaq   0x1e6cd(%rip), %rax       ; "attempted to retain deallocated object"
    0x111e91747 <+7>:  movq   %rax, 0x58612(%rip)       ; gCRAnnotations + 8
    0x111e9174e <+14>: int3   
->  0x111e9174f <+15>: nop    

私の知る限り、親の deinit がまだ完了していないため、親はまだ存在するはずです。unownedそれでも、このエラーは、子が親への参照にアクセスできなくなったことを示唆しているようです。

誰でもこれに光を当てることができますか?

4

3 に答える 3

1

この場合、所有されていない(安全でない)がそれを行います。しかし、個人的には、objective-c コードのブリッジ以外には unowned(unsafe) を使用しません。

可能であれば、 deinit() から child.doStuff() を呼び出す必要がないようにします。時間が必要なときに自分のコードが呼び出す .unload() メソッドを追加しただけの同様のケースがありました。上記の例では、ViewController はこの責任を受け入れることができます。

そして、ユートピア的な解決策は、もちろん可能であれば、オブジェクトが設計によってそれほど絡み合っていない方法を見つけることだと思います。

unload() シナリオの例: (ターミナル repl でテストしたため、UIKit はありません)

import Foundation

class ViewController {
  let parent = Parent()

  deinit {
    parent.unload()
  }
}

class Parent {

  init() {
    child.doStuff()
  }

  func unload() {
    // Code used to be in deinit
    child.doStuff()
  }

  lazy private var child : Child = Child(parent : self)
}

class Child {

  init(parent : Parent) {
    self.parent = parent
  }

  func doStuff() {
    println(self.parent)
  }

  private unowned var parent : Parent
}

var vc:ViewController? = ViewController()
vc = nil
于 2015-05-29T09:45:17.333 に答える
0

を使用するとunowned(unsafe)、この問題が修正されます。一般的には非常に危険に思えますが、このコンテキストでは、子が存在する間は親が存在することが保証されているため問題ありません。

于 2015-05-29T08:45:52.030 に答える