一次将多个引用类型值设置为 nil

Set multiple reference type values to nil at once

假设我有一个 UIView? 数组,默​​认值是:

var firstView: UIView? = UIView()
var secondView: UIView? = UIView()
let views = [firstView, secondView]

我想将数组中的每个值更改为 nil。理想的解决方案是遍历数组的元素并将它们设置为 nil。但是,这不起作用:

print(firstView) //Optional(<UIView: [address]; frame = (0 0; 0 0); layer = <CALayer: [address]>>)

for i in 0 ..< views.count {
    views[i] = nil
}

//firstView is still not nil
print(firstView) //Optional(<UIView: [address]; frame = (0 0; 0 0); layer = <CALayer: [address]>>)

有什么解决方案?

,不能直接修改实例变量的地址。此问题的一些可能解决方案:

  • ,您只能将视图存储在该数组中,而不能存储在其他任何地方。这样,当您使数组中的每个元素 nil 时,将不会有任何视图引用。但是,这很容易产生过长或难以理解的代码。
  • UIViews 的通常更好的解决方案是创建自定义视图 并将所有元素放入其中,否则您将存储在数组中。这样,您可以轻松地使一个视图 nil 并且所有子视图都将是 nil (因为它们依赖于父视图)。

您可以使用 KeyPaths:

class Foo {
    let views = [\Foo.view1, \Foo.view2]

    var view1: UIView? = UIView()
    var view2: UIView? = UIView()

    func freeAll() {
        print(view1 as Any, view2 as Any)

        for keyPath in views {
            self[keyPath: keyPath] = nil
        }

        print(view1 as Any, view2 as Any)
    }
}

let foo = Foo()
foo.freeAll()

输出:

Optional(<UIView: 0x7fc5c4107bb0; frame = (0 0; 0 0); layer = <CALayer: 0x60000213e760>>) Optional(<UIView: 0x7fc5c41057a0; frame = (0 0; 0 0); layer = <CALayer: 0x60000213d780>>)
nil nil

在这种情况下,views 数组不包含对对象的引用,而是存储 KeyPaths,您可以将其视为如何找到它们的方向。这允许您访问对象并根据需要将它们设置为 nil