Ich habe zwei CoreData-Entitäten mit einer Eins-zu-Eins-Beziehung. Ich möchte Strukturen basierend auf diesen Entitäten erstellen. Mein Code:
%Vor% Aber ich habe einen Fehler: Value type 'DetailedPin' cannot have a stored property that references itself
. Und der gleiche Fehler für Pin
struct. Wie kann ich mit diesem Problem umgehen? Danke.
Das Problem ist, dass ein Optional
seinen Wrapped
-Wert inline speichert (siehe Mike Ashs fantastischer Blog-Beitrag für weitere Informationen zu diesem Thema - was bedeutet, dass eine Optional
-Instanz (egal ob nil
oder nicht) mindestens belegen wird die gleiche Menge an Speicher wie der Typ, den Sie in seiner .some
-Fall speichern möchten (der Wrapped
-Typ).
Da Ihre Pin
struct eine Eigenschaft vom Typ DetailedPin?
hat und DetailedPin
eine Eigenschaft vom Typ Pin?
hat, wäre unendlicher Speicher erforderlich, um diese Werte inline zu speichern.
Die Lösung besteht also einfach darin, eine indirekte Ebene hinzuzufügen. Eine Möglichkeit wäre, Pin
und / oder DetailedPin
als Referenztyp (dh class
) als @ dfri hat vorgeschlagen .
Wenn Sie jedoch die Wertesemantik von Pin
und DetailedPin
beibehalten möchten, besteht eine Option darin, einen Wrappertyp zu erstellen, der von einer Klasseninstanz unterstützt wird, um die erforderliche Indirektion bereitzustellen:
Sie können jetzt einfach den Indirect
-Wrapper für eine (oder beide) Ihrer structs-Eigenschaften verwenden:
Eine Eins-zu-eins-Beziehung zwischen zwei Entitäten ist nur gültig, wenn mindestens eine der Verbindungen zwischen diesen Entitäten vom -Referenz -Typ ist; Für zwei reine Werttypen wird ihre Eins-zu-Eins-Beziehung rekursiv.
Angenommen, Sie erstellen ein Objekt vom Werttyp DetailedPin
. Es enthält eine Instanzeigenschaft ( pin
) des Werttyps Pin
, was bedeutet, dass diese Instanzeigenschaft Teil des Werts ist, der die Instanz von DetailedPin
ist. Die Instanzeigenschaft pin
von und die Instanz von DetailedPin
hat nun den Wert Pin
, der selbst eine Instanzeigenschaft ( detailedPin
) vom Werttyp DetailedPin
enthält. Dieses Instanzmitglied detailedPin
ist wiederum _ein Teil des Wertes, der die Instanz pin
) ist, aber wiederum besitzt detailedPin
selbst einen Wert vom Typ pin
, und so wird der rekursive Tanz fortgesetzt ...
Sie können dies umgehen, indem Sie eine Ihrer Strukturen in einen Referenztyp verwandeln ( class
):
Beachten Sie, dass die rekursive Beziehung, die oben behandelt wird, nicht direkt mit ARC (automatische Referenzzählung) oder starken Referenzzyklen zusammenhängt, sondern dass der Wert einer Werttypinstanz die Instanz selbst und der Wert aller darin enthaltenen Werttyp- (Teil-) Eigenschaften (sowie die Referenz auf alle darin enthaltenen Referenztyp- (Teil-) Eigenschaften).
Seien Sie vorsichtig, wenn Sie beide Eins-zu-Eins-Entitäten als Referenztypen definieren: In diesem Fall müssen Sie sicherstellen, dass eine der Referenzen zwischen den beiden Typen weak
ist. Zum Beispiel:
Falls Sie weak
oben nicht angeben (d. h., dass sich beide durch die standardmäßigen starken Referenzen gegenseitig ansprechen), haben Sie einen starken Referenzzyklus zwischen den beiden aufeinander bezogenen Instanzen
Wie hier erwähnt: indirekte enums und structs , könnte eine elegante Lösung sein, Ihre Referenz innerhalb einer Enum mit einem indirect
case.
In Ihrem Beispiel würde dies Folgendes ergeben:
%Vor%oder direkt, je nach Ihren Bedürfnissen:
%Vor% Jenseits meines Verständnisses sagt indirect
dem Compiler, dass es eine Rekursion in Ihrer Enumeration gibt, und es sollte die notwendige Indirektionsebene einfügen .