A one to one relationship between two entities is only valid if at least one of the connections between these entities is of reference type; for two pure value types, their one to one relationsship will become a recursive one.
Say you create an object of the value type DetailedPin. It contains an instance property (pin) of the value type Pin, which means this instance property is part of the value that is the instance of DetailedPin. Now, the instance property pin of and instance of DetailedPin, is of the value type Pin, which itself contains an instance property (detailedPin) of value type DetailedPin. This instance member detailedPin is, again, _a part of the value that is the instance pin), but again, detailedPin itself owns a value of type pin, and so the recursive dance continues ...
You can circumvent this by turning one of your structures into a reference type (class):
struct DetailedPin {
var pin: Pin?
}
class Pin {
var detailedPin: DetailedPin?
}
// or
class DetailedPin {
var pin: Pin?
}
struct Pin {
var detailedPin: DetailedPin?
}
Note that the recursive relationship covered above is not directly related to ARC (automatic reference counting) or strong reference cycles, but the fact that the value of a value type instance is the instance itself and the value of all value type (sub-)properties it contains (as well as the reference to all reference type (sub-)properties it contains).
Just take care if you choose to let both your one to one entities be reference types: in this case you must make sure that one of the references between the two types are weak. E.g.:
class DetailedPin {
weak var pin: Pin?
}
class Pin {
var detailedPin: DetailedPin?
}
// or
class DetailedPin {
var pin: Pin?
}
class Pin {
weak var detailedPin: DetailedPin?
}
In case you leave out weak above (i.e., let both refer to each other by the default strong references), you will have a strong reference cycle between the two instances referring to each other
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