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

ale*_*son 21 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
Run Code Online (Sandbox Code Playgroud)

您的输出控制台应显示:

target set to view
target set to nil
Run Code Online (Sandbox Code Playgroud)

我的控制台显示

target set to view
Run Code Online (Sandbox Code Playgroud)

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

Wol*_*lly 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()
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

请注意,在A取消分配的实例和在B变为nil的实例中的弱引用都不是被调用的属性观察者.只有在分配给Ba的直接情况下才被称为.

  • 假设我被迫使用`weak var`以避免保留周期.当我真的想关心时,为什么我被迫进入这种*不关心*的态度?我必须遗漏软件架构中明显的东西...... (6认同)