两个实体之间的一对一关系只有在这些实体之间的至少一个连接是 reference 类型时才有效;对于两种纯值类型,它们的一对一关系将变为递归关系。
假设您创建了一个值类型为DetailedPin 的对象。它包含一个值类型为Pin 的实例属性(pin),这意味着该实例属性是值的一部分,它是DetailedPin 的实例。现在,DetailedPin 的实例属性pin 和DetailedPin 的实例是值类型Pin,它本身包含值类型detailedPin 的实例属性(detailedPin)。这个实例成员detailedPin 再次是实例pin 值的一部分),但同样,detailedPin 本身拥有一个类型为pin 的值,因此递归舞蹈继续......
您可以通过将其中一个结构转换为引用类型 (class) 来规避此问题:
struct DetailedPin {
var pin: Pin?
}
class Pin {
var detailedPin: DetailedPin?
}
// or
class DetailedPin {
var pin: Pin?
}
struct Pin {
var detailedPin: DetailedPin?
}
请注意,上面提到的递归关系与 ARC(自动引用计数)或强引用循环没有直接关系,而是值类型实例的值是实例本身和 值 它包含的所有值类型(子)属性(以及对它包含的所有引用类型(子)属性的引用)。
如果您选择让您的一对一实体都是引用类型,请注意:在这种情况下,您必须确保这两种类型之间的引用之一是 weak。例如:
class DetailedPin {
weak var pin: Pin?
}
class Pin {
var detailedPin: DetailedPin?
}
// or
class DetailedPin {
var pin: Pin?
}
class Pin {
weak var detailedPin: DetailedPin?
}
如果您在上面遗漏了weak(即,让两者通过默认的强引用相互引用),您将在两个相互引用的实例之间有一个强引用循环
class DetailedPin {
var pin: Pin?
deinit { print("DetailedPin instance deinitialized") }
}
class Pin {
var detailedPin: DetailedPin?
deinit { print("Pin instance deinitialized") }
}
func foo() {
let pin = Pin()
let detailedPin = DetailedPin()
pin.detailedPin = detailedPin
detailedPin.pin = pin
}
foo() // no deinit called