参考类型内部值类型

时间:2017-04-04 22:05:05

标签: swift memory-management value-type reference-type deinit

我正在探索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. 还有别的吗?

2 个答案:

答案 0 :(得分:5)

每个结构A 副本将共享相同B的引用。从头开始创建的每个 new 结构A都将包含一个全新的B对象。

strong references 为零时,系统会调用B.deint(例如,您的var b是其中一个强引用)。例如,如果只有A值保存对给定B对象的引用,那么那些将需要超出范围以将对该对象的所有引用(或其盒装副本)归零也可以解除分配,但这可能是另一个问题的主题。)

代码设计。如果这些听起来太混乱并阻碍了您的应用程序进度(到目前为止没有真正的实际好处),您可以考虑将B重构为结构。例如,甚至Apple recommends considering value types来设计模型层This blog post也可能有助于下定决心。

答案 1 :(得分:1)

你可以在游乐场测试:

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.