知道Swift中弱变量何时变为零?

时间:2014-06-19 22:37:06

标签: ios swift

我们说weak var view: UIView?中有一个class Button {}。有没有办法知道view何时失去参考并成为nil

我尝试使用weak var view: UIView? {}(也称为计算属性)来覆盖set {},但这不起作用,因为现在它已成为计算属性而无法使用存储一个弱引用(多么烦人!)。

修改

@fqdn 的答案没有使用此代码...在Xcode Playground中试用

import UIKit

class Test {
  weak var target: UIView? {
    willSet {
      if !newValue { println("target set to nil") }
      else { println("target set to view") }
    }
  }
}

class Button {
  var view: UIView? = UIView()
}

var t = Test()
var b = Button()
t.target = b.view
b.view = nil // t.target's willSet should be fired here

您的输出控制台应显示:

target set to view
target set to nil

我的控制台显示

target set to view

b.view是UIView实例的强引用。 t.target是弱参考。因此,如果b.view设置为nil,则取消分配UIView实例,t.target将等于nil。

1 个答案:

答案 0 :(得分:13)

如果你的按钮持有对另一个视图的引用,它应该是该视图的所有者(即,它应该具有强引用),或者当该视图消失时它不应该关心(即,它的弱引用它变为零。)当弱引用变为零时没有通知,这是设计的。

特别是,当弱引用变为nil时,不会调用Swift属性观察器,如下面的代码所示:

class A : CustomStringConvertible {
    var s: String?

    init(s: String) {
        self.s = s;
        print("\(self) init")
    }

    deinit {
        print("\(self) deinit")
    }

    var description: String {
        get { return "[A s:\(s ?? "nil")]" }
    }
}

class B : CustomStringConvertible {
    weak var a:A? {
        willSet {
            print("\(self) willSet a")
        }
        didSet {
            print("\(self) didSet a")
        }
    }

    init(a: A?) {
        self.a = a
        print("\(self) init")
    }

    deinit {
        print("\(self) deinit")
    }

    var description: String {
        get { return "[B a:\(a == nil ? "nil" : String(describing: a!))]" }
    }
}

func work() {
    var a: A? = A(s: "Hello")
    var b = B(a: a)
    print("\(b)")
    a = nil
    print("\(b)")
    b.a = A(s: "Goodbye")
}

work()

调用work()时,控制台会提供以下输出:

[A s:Hello] init
[B a:[A s:Hello]] init
[B a:[A s:Hello]]
[A s:Hello] deinit
[B a:nil]
[A s:Goodbye] init
[B a:nil] willSet a
[B a:[A s:Goodbye]] didSet a
[A s:Goodbye] deinit
[B a:nil] deinit

请注意,在A解除分配的实例和B的实例中的弱引用都不是n的情况下,属性观察者都会被调用。只有在分配给B.a的直接情况下才会被称为。