4

我正在探索 Swift 值类型,尤其是结构,以更好地了解它在不同场景中的用途。我很惊讶地看到枚举如何用于构建二叉搜索树,使用indirect它引入了一层薄薄的参考语义。

enum BinarySearchTree<T: Comparable> {
  case empty
  case leaf(T)
  indirect case node(BinarySearchTree, T, BinarySearchTree)
}

现在来到真正的问题,我正在努力寻找的是,值类型中的引用类型会发生什么。这种关系将如何运作?比如内存管理,对象生命周期。

例如

class B {
    var data: Int = 0

    deinit {
        print("deallocated!")
    }

}

struct A {
    var b = B()
}

在上述情况下,值类型持有对引用类型的引用。

  1. 什么时候会deinit被叫到?
  2. 每个类型的新结构实例是否都会A引用相同的类实例,B或者它们会有所不同。
  3. 我应该注意什么或者这是代码异味?
  4. 还要别的吗?
4

2 回答 2

6

每个结构A 副本都将共享B. 从头开始创建的每个structA都将包含一个全新的B对象。

当对它的强引用B.deint为零时将调用(例如,您是这些强引用之一)。例如,如果只有值包含对给定对象的引用,那么那些将需要超出范围以将对该对象的所有引用归零(或者它们的盒装副本也被释放,但这可能是另一个问题的主题。)var bAB

代码设计。如果这些听起来太令人困惑并且阻碍了您的应用程序进度(到目前为止没有真正的实际好处),您也可以考虑重构B为结构。例如,甚至Apple 也建议考虑值类型来设计模型层这篇博文也可能有助于您下定决心。

于 2017-04-04T22:38:47.827 回答
3

您可以在操场上进行测试:

class B {
    var data: Int = 0

    deinit {
        print("deallocated!")
    }
}

struct A {
    var b = B()
}

var a1: A? = A()
var a2: A? = A()
var a3: A? = a1

// Do the two instances of struct A share the same instance of class B?
a1?.b === a2?.b // false

// Do copies of instances of struct A share the same instance of class B?
a1?.b === a3?.b // true

// When will deinit be called?
a1 = nil    // Not yet, a3 still holds a strong reference to the shared instance of class B
a3 = nil    // Now! There are no longer any strong references to the shared instance of class B, so it is deallocated.
于 2017-04-04T22:46:49.250 回答