代码之家  ›  专栏  ›  技术社区  ›  Tamás Sengel RIJO JOSEPH

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

  •  1
  • Tamás Sengel RIJO JOSEPH  · 技术社区  · 6 年前

    假设我有一系列 UIView? 默认值为:

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

    我想将数组中的每个值更改为 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]>>)
    

    解决这个问题的办法是什么?

    2 回复  |  直到 6 年前
        1
  •  1
  •   vacawama    6 年前

    你可以用 KeyPath S:

    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 数组不包含对对象的引用,而是存储 关键路径 你可以把它看作是如何找到它们的方向。允许您访问对象并将其设置为 nil 如果需要。

        2
  •  0
  •   Tamás Sengel RIJO JOSEPH    6 年前

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

    • As MartinR points out ,您只能将视图存储在该数组中,而不能存储在其他任何地方。这样,当您在数组中创建每个元素时 nil ,视图没有任何引用。但是,这很容易产生过长或难以理解的代码。
    • 通常更好的解决方案 UIView S是 创建自定义视图 并将所有要存储在数组中的元素放入其中。这样,你就可以很容易地看到 所有的子视图 (因为它们依赖于超视界)。