In meiner Lion-App habe ich dieses Datenmodell:
Die Beziehung im subitems
Inneren Item
ist geordnet .
Xcode 4.1 (Build 4B110) hat sich für mich die Datei erstellt Item.h
, Item.m
, SubItem.h
und SubItem.h
.
Hier ist der Inhalt (automatisch generiert) von Item.h
:
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class SubItem;
@interface Item : NSManagedObject {
@private
}
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSOrderedSet *subitems;
@end
@interface Item (CoreDataGeneratedAccessors)
- (void)insertObject:(SubItem *)value inSubitemsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromSubitemsAtIndex:(NSUInteger)idx;
- (void)insertSubitems:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeSubitemsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInSubitemsAtIndex:(NSUInteger)idx withObject:(SubItem *)value;
- (void)replaceSubitemsAtIndexes:(NSIndexSet *)indexes withSubitems:(NSArray *)values;
- (void)addSubitemsObject:(SubItem *)value;
- (void)removeSubitemsObject:(SubItem *)value;
- (void)addSubitems:(NSOrderedSet *)values;
- (void)removeSubitems:(NSOrderedSet *)values;
@end
Und hier ist der Inhalt (automatisch generiert) von Item.m
:
#import "Item.h"
#import "SubItem.h"
@implementation Item
@dynamic name;
@dynamic subitems;
@end
Wie Sie sehen können, Item
bietet die Klasse eine Methode namens addSubitemsObject:
. Leider, wenn Sie versuchen, es auf diese Weise zu verwenden:
Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";
SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];
[item addSubitemsObject:subItem];
Dieser Fehler wird angezeigt:
2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
Können Sie mir helfen?
Aktualisieren:
Nach nur 1.787 Tagen nach meinem Fehlerbericht schrieb mir Apple heute (1. August 2016) Folgendes : "Bitte überprüfen Sie dieses Problem mit der neuesten Beta-Version von iOS 10 und aktualisieren Sie Ihren Fehlerbericht unter bugreport.apple.com mit Ihren Ergebnissen." . Hoffen wir, dass dies der richtige Zeitpunkt ist :)
mutableOrderedSetValueForKey:
)Antworten:
Ich habe Ihr Setup sowohl mit Ihrem Datenmodell als auch mit einem meiner eigenen mit unterschiedlichen Namen reproduziert. Ich habe in beiden Fällen den gleichen Fehler erhalten.
Sieht aus wie ein Fehler in Apples automatisch generiertem Code.
quelle
Ich bin damit einverstanden, dass hier ein Fehler vorliegt. Ich habe die Implementierung des Add Object Setters so geändert, dass sie korrekt an ein NSMutableOrderedSet angehängt wird.
Durch erneutes Zuweisen des Satzes zu self.subitems wird sichergestellt, dass die Will / DidChangeValue-Benachrichtigungen gesendet werden.
quelle
Ich habe beschlossen, die Lösung durch Implementierung aller erforderlichen Methoden zu verbessern:
quelle
willChangeValueForKey:withSetMutation:usingObjects
, was Sie erfolgreich vermieden haben. Danach einfach[[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values]
oder[[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values]
nach Bedarf verwenden. Siehe meine Antwort für Details.Ja, dies ist definitiv ein Core Data-Fehler. Ich habe vor einiger Zeit einen ObjC-Runtime-basierten Fix geschrieben, aber zu der Zeit dachte ich, dass er bald behoben sein würde. Wie auch immer, kein solches Glück, also habe ich es auf GitHub als KCOrderedAccessorFix gepostet . Umgehen Sie das Problem bei allen Ihren Entitäten:
Eine Einheit im Besonderen:
Oder nur für eine Beziehung:
quelle
- (BOOL)kc_needsOrderedSetAccessorFix;
oder etwas hinzu, das die Foundation / iOS-Version überprüft.objc_msg_send
)Anstatt eine Kopie zu erstellen, schlage ich vor, den Accessor in NSObject zu verwenden, um Zugriff auf das NSMutableOrderedSet der Beziehungen zu erhalten.
zB die Hierzu beziehen sich Core Data Release Notes für iOS v5.0 .
In einem kurzen Test hat es in meiner Anwendung funktioniert.
quelle
NSStringFromSelector(@selector(subitems))
:)Ich habe den Fehler verfolgt. Es kommt in vor
willChangeValueForKey:withSetMutation:usingObjects:
.Dieser Aufruf löst eine Reihe von Benachrichtigungen aus, die möglicherweise schwer zu verfolgen sind, und natürlich können Änderungen an einem Antwortenden Auswirkungen auf einen anderen haben. Ich vermute, dass Apple deshalb nichts unternommen hat.
Es ist jedoch in Set in Ordnung und es sind nur die Set-Operationen auf einem OrderedSet, die nicht funktionieren. Das heißt, es gibt nur vier Methoden, die geändert werden müssen. Daher habe ich nur die Set-Operationen in ihre entsprechenden Array-Operationen konvertiert. Diese funktionieren perfekt und minimale (aber notwendige) Gemeinkosten.
Auf einer kritischen Ebene weist diese Lösung einen kritischen Fehler auf. Wenn Sie Objekte hinzufügen und eines der Objekte bereits vorhanden ist, wird es entweder nicht hinzugefügt oder an den Ende der geordneten Liste verschoben (ich weiß nicht, welches). In beiden Fällen unterscheidet sich der erwartete geordnete Index des Objekts zum Zeitpunkt unserer Ankunft
didChange
von dem erwarteten. Dies kann die Apps einiger Leute beschädigen, hat jedoch keine Auswirkungen auf meine, da ich immer nur neue Objekte hinzufüge oder deren endgültige Position bestätige, bevor ich sie hinzufüge.Natürlich gibt es eine einfachere Lösung. es ist wie folgt;
quelle
In den Apple-Dokumenten zu vielen Beziehungen heißt es: Sie sollten mit auf das veränderbare Proxy-Set oder das geordnete Set zugreifen
Durch Ändern dieses Satzes werden Beziehungen zu Ihrem verwalteten Objekt hinzugefügt oder entfernt. Zugriff auf die veränderbare geordnete Menge mit dem Accessor, ob mit [] oder. Notation ist falsch und wird fehlschlagen.
quelle
Erhielt den gleichen Fehler, @ LeeIII-Lösung funktionierte für mich (danke!). Ich schlage vor, es leicht zu ändern:
Inhalt von
Item+category.m
:quelle
Wenn Sie Mogenerator verwenden, dann anstelle von
Verwenden Sie einfach:
quelle
mogenerator
aber ich habe immer noch den Fehler.Persönlich habe ich gerade die Aufrufe der von CoreData generierten Methoden durch direkte Aufrufe der Methode ersetzt, wie in einer anderen Lösung von @Stephan beschrieben:
Dadurch werden keine Kategorien mehr benötigt, die später mit einer Lösung von Apple für den generierten Code in Konflikt geraten könnten, wenn der Fehler behoben ist.
Dies hat das zusätzliche Plus, der offizielle Weg zu sein!
quelle
addObject:
zweimal angerufen?Es scheint, dass, wenn Sie das Elternteil mit dem Kind verknüpfen, indem Sie das Elternteil auf das Kind setzen und nicht umgekehrt, es ohne Absturz funktioniert.
Wenn Sie dies tun:
anstatt
Es sollte funktionieren, zumindest funktioniert es unter iOS 7 und hatte keine Probleme mit der Beziehung.
quelle
Ich hatte das gleiche Problem, aber nur, wenn ich etwas anderes ausprobierte als das, was ich getan hatte. Ich kann den Code für subItem nicht sehen, aber ich gehe davon aus, dass er einen umgekehrten Link zum Element hat. Nennen wir diesen Reveres-Link "parentItem". Die einfachste Lösung ist folgende:
Der Effekt ist, dass es den eigenen Code von Apple verwendet und einfach und sauber ist. Außerdem wird das Set automatisch hinzugefügt und alle Beobachter werden aktualisiert. Kein Problem.
quelle
Ich habe dieses Problem einfach nicht verstanden und es mit einer viel einfacheren Implementierung als den anderen hier beschriebenen gelöst. Ich benutze einfach die verfügbaren Methoden
NSManagedObject
für den Umgang mit Beziehungen, wenn ich keine Unterklassen benutze.Eine Beispielimplementierung zum Einfügen einer Entität in eine
NSOrderedSet
Beziehung würde folgendermaßen aussehen:Dies funktioniert perfekt und wurde von mir verwendet, bevor ich zu
NSManagedObject
Unterklassen gewechselt bin .quelle
Dieses Problem trat mir bei der Migration eines Projekts von Objective-C auf Swift 2 mit XCode 7 auf . Dieses Projekt hat früher funktioniert, und das aus gutem Grund: Ich habe MOGenerator verwendet, der Ersatzmethoden zur Behebung dieses Fehlers hatte. Nicht alle Methoden erfordern jedoch einen Austausch.
Hier ist die vollständige Lösung mit einer Beispielklasse, die sich so weit wie möglich auf Standard-Accessoren stützt.
Nehmen wir an, wir haben eine Liste mit bestellten Artikeln
Zuerst ein schneller Gewinn, wenn Sie eine Eins-zu-Viele-Beziehung haben. Am einfachsten ist es, einfach Folgendes zu tun:
anstatt
Nun, wenn das keine Option ist , ist hier, was Sie tun können:
Wenn Sie Objective-C verwenden, können Sie natürlich genau das Gleiche tun, da ich hier überhaupt auf die Idee gekommen bin :)
quelle
Leelll, sind Sie sicher, dass nach einer solchen benutzerdefinierten Einrichtung der in diesem Satz gespeicherten NSMutableOrderedSet-Werte von CoreData korrekt in der Datenbank gespeichert werden? Ich habe das nicht überprüft, aber es sieht so aus, als ob CoreData nichts über NSOrderedSet weiß und NSSet als zu viele Beziehungscontainer erwartet.
quelle
Ich denke, jeder vermisst das eigentliche Problem. Es liegt nicht in den Accessor-Methoden, sondern in der Tatsache, dass
NSOrderedSet
es sich nicht um eine Unterklasse von handeltNSSet
. Wenn-interSectsSet:
also eine geordnete Menge als Argument aufgerufen wird, schlägt dies fehl.scheitert mit
*** -[NSSet intersectsSet:]: set argument is not an NSSet
Es sieht so aus, als ob das Update darin besteht, die Implementierung der Set-Operatoren so zu ändern, dass sie die Typen transparent behandeln. Kein Grund warum a
-intersectsSet:
mit einem bestellten oder ungeordneten Set arbeiten sollte.Die Ausnahme tritt in der Änderungsbenachrichtigung auf. Vermutlich in dem Code, der die umgekehrte Beziehung behandelt. Da passiert es nur, wenn ich eine umgekehrte Beziehung setze.
Das Folgende hat den Trick für mich getan
quelle
Ich habe gerade das Problem in Swift (Xcode 6.1.1) bekommen.
Die Antwort lautete: KEINE METHODE ODER ZUSÄTZLICHE DINGE CODE in Ihren NSManagedObject-Unterklassen codieren. Ich denke, es ist ein Kompilatorfehler. Sehr seltsamer Fehler ..
Ich hoffe es hilft ..
quelle
Ich habe dieses Problem gelöst, indem ich das Inverse auf No Inverse gesetzt habe. Ich weiß nicht warum. Vielleicht gibt es einen Apple Bug.
quelle
Ich habe die gleiche Situation mit einem Element namens "Signale" anstelle von "Unterelementen". Die Lösung mit Tempset funktioniert in meinen Tests. Außerdem hatte ich ein Problem mit der Methode removeSignals :. Diese Überschreibung scheint zu funktionieren:
Wenn es einen besseren Weg gibt, lassen Sie es mich bitte wissen. Meine Werteingabe beträgt nie mehr als 10 bis 20 Elemente, daher ist die Leistung kein großes Problem. Bitte weisen Sie jedoch auf relevante Informationen hin.
Vielen Dank,
Damien
quelle
Ich habe diese Frage gefunden, indem ich nach der Fehlermeldung gegoogelt habe, und wollte nur darauf hinweisen, dass ich auf etwas andere Weise auf diesen Fehler gestoßen bin (ohne geordnete Sätze zu verwenden). Dies ist keine echte Antwort auf die gegebene Frage, aber ich poste sie hier, nur für den Fall, dass sie für alle anderen hilfreich ist, die bei der Suche auf diese Frage stoßen.
Ich habe eine neue Modellversion hinzugefügt, einige Beziehungen zu vorhandenen Modellen hinzugefügt und die add * Object-Methoden in der Header-Datei selbst definiert. Als ich versuchte, sie anzurufen, bekam ich den obigen Fehler.
Nachdem ich meine Modelle überprüft hatte, stellte ich fest, dass ich dummerweise vergessen hatte, das Kontrollkästchen "To-Many Relationship" zu aktivieren.
Wenn Sie also darauf stoßen und keine bestellten Sets verwenden, überprüfen Sie Ihr Modell.
quelle
Ich habe eine Lösung für diesen Fehler gefunden, die für mich funktioniert. Ich ersetze dies einfach:
mit diesem:
quelle
Bessere Version der richtigen Antwort in SWIFT
quelle
Ich fand, dass die Verwendung der Methode von LeeIII funktioniert hat, aber bei der Profilerstellung stellte sich heraus, dass sie drastisch langsam war. Das Parsen von 1000 Elementen dauerte 15 Sekunden. Durch Auskommentieren des Codes zum Hinzufügen der Beziehung wurden 15 Sekunden zu 2 Sekunden.
Meine Problemumgehung (die schneller, aber viel hässlicher ist) besteht darin, ein temporäres veränderbares Array zu erstellen und es dann in die geordnete Menge zu kopieren, wenn das gesamte Parsen abgeschlossen ist. (Dies ist nur ein Leistungsgewinn, wenn Sie viele Beziehungen hinzufügen möchten).
Ich hoffe das hilft jemand anderem!
quelle
Robert,
Ich bin damit einverstanden, dass Ihre Antwort dafür funktioniert, aber denken Sie daran, dass es bereits eine automatisch erstellte Methode gibt, um einer Beziehung eine ganze Reihe von Werten hinzuzufügen. Die Dokumentation von Apple ( hier im Abschnitt "Zu viele Beziehungen" oder hier im Abschnitt "Benutzerdefinierte Methoden für den Zugriff auf viele Beziehungen") implementiert sie folgendermaßen:
Mit dieser Methode können Sie Ihre Beziehungen problemlos außerhalb der Kerndaten kompilieren und dann alle auf einmal hinzufügen. Es könnte weniger hässlich sein als die von Ihnen vorgeschlagene Methode;)
quelle
Ich bin mir ziemlich sicher, dass es endlich in iOS 10 Beta 6 behoben ist !
quelle