A one-to-one relationship between two objects is valid only if at least one of the connections between these objects has a reference type; for two pure value types, their one-to-one relationships will become recursive.
Suppose you created an object of type DetailedPin . It contains an instance property ( pin ) of the pin value type, which means that this instance property is part of the value that is the DetailedPin instance. Now the pin instance property and the DetailedPin instance have a pin value type, which itself contains the instance property ( DetailedPin ) of the DetailedPin value type. This member of the DetailedPin instance is again part of the value that is the pin instance), but again, DetailedPin itself owns a pin value, and so the recursive dance continues ...
You can get around 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 relation described above is not directly related to ARC (automatic reference counting) or strong reference loops, but the fact that the value of the value type instance is the instance itself and the value of the entire value type (sub -) that it contains (and also a link to all the properties of the reference type (sub) that it contains).
Just take care if you decide that both of your one on one are reference types: in this case, you must make sure that one of the links between the two types is weak . For example:.
class DetailedPin { weak var pin: Pin? } class Pin { var detailedPin: DetailedPin? } // or class DetailedPin { var pin: Pin? } class Pin { weak var detailedPin: DetailedPin? }
If you exit weak above (i.e., both link to each other by default strong links), you will have a strong link loop between two instances that link 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
dfri
source share