363 Stimmen

Ausnahme, die in den von NSOrderedSet generierten Accessors ausgelöst wird

In meiner Lion-Anwendung habe ich dieses Datenmodell:

enter image description here

Die Beziehung subitems innerhalb Item ist bestellt .

Xcode 4.1 (Build 4B110) hat für mich die Datei Item.h , Item.m , SubItem.h y 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 (selbst erstellte) Inhalt von Item.m :

#import "Item.h"
#import "SubItem.h"

@implementation Item

@dynamic name;
@dynamic subitems;

@end

Wie Sie sehen können, ist die Klasse Item bietet 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 auftreten:

2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet

Können Sie mir helfen?

Aktualisierung:

Nach nur 1.787 Tagen seit meiner Fehlermeldung schrieb mir Apple heute (1. August 2016) Folgendes: "Bitte überprüfen Sie dieses Problem mit dem neuesten iOS 10 Beta-Build und aktualisieren Sie Ihren Fehlerbericht unter bugreport.apple.com mit Ihren Ergebnissen." . Hoffen wir, dass dies der richtige Zeitpunkt ist :)

5voto

Cata Punkte 10973

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 es also tun:

[child setParent:parent]

anstelle von

[parent setChildObects:child]

Es sollte funktionieren, zumindest funktioniert es unter iOS 7 und ich hatte keine Probleme mit der Beziehung.

3voto

Owen Godfrey Punkte 3341

Ich hatte das gleiche Problem, aber nur, wenn ich etwas anderes ausprobierte als das, was ich bisher getan hatte. Ich kann den Code für subItem nicht sehen, aber ich gehe davon aus, dass er einen umgekehrten Link zu item hat. Nennen wir diesen umgekehrten Link "parentItem", dann ist die einfachste Lösung diese:

Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
item.name = @"FirstItem";

SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];

//[item addSubitemsObject:subItem];
subItem.parentItem = item;

Der Effekt ist, dass es den eigenen Code von Apple verwendet und einfach und sauber ist. Außerdem wird die Menge automatisch ergänzt, und alle Beobachter werden aktualisiert. Kein Problem.

3voto

Arnaud Punkte 16317

Dieses Problem ist mir bei der Migration eines Projekts von Objective-C nach Mauersegler 2 con XCode 7 . Dieses Projekt hat früher funktioniert, und das aus gutem Grund: Ich habe MOGenerator verwendet, der Ersatzmethoden zur Behebung dieses Fehlers hatte. Aber nicht alle Methoden erfordern eine Ersetzung.

Hier ist also die vollständige Lösung mit einer Beispielklasse, die so weit wie möglich auf Standard-Accessors zurückgreift.

Nehmen wir an, wir haben eine Liste mit geordneten Elementen

Zunächst eine schneller Erfolg wenn Sie eine ein/zu-viele-Beziehung haben, ist es am einfachsten, einfach zu tun:

item.list = list

anstelle von

list.addItemsObject(item)

Ahora, wenn das nicht möglich ist dann können Sie Folgendes tun:

// Extension created from your DataModel by selecting it and
// clicking on "Editor > Create NSManagedObject subclass…"

extension List {
  @NSManaged var items: NSOrderedSet?
}

class List

  // Those two methods work out of the box for free, relying on
  // Core Data's KVC accessors, you just have to declare them
  // See release note 17583057 https://developer.apple.com/library/prerelease/tvos/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc7_release_notes.html
  @NSManaged func removeItemsObject(item: Item)
  @NSManaged func removeItems(items: NSOrderedSet)

  // The following two methods usually work too, but not for NSOrderedSet
  // @NSManaged func addItemsObject(item: Item)
  // @NSManaged func addItems(items: NSOrderedSet)

  // So we'll replace them with theses

  // A mutable computed property
  var itemsSet: NSMutableOrderedSet {
    willAccessValueForKey("items")
    let result = mutableOrderedSetValueForKey("items")
    didAccessValueForKey("items")
    return result
  }

  func addItemsObject(value: Item) {
    itemsSet.addObject(value)
  }

  func addItems(value: NSOrderedSet) {
    itemsSet.unionOrderedSet(value)
  }
end

Wenn Sie Objective-C verwenden, können Sie natürlich genau das Gleiche tun, denn dort habe ich die Idee ursprünglich hergeleitet :)

3voto

Eugene Dudnyk Punkte 5250

Ich stimme zu, dass hier vielleicht ein Fehler vorliegt. Ich habe die Implementierung des add object >setter geändert, um korrekt an ein NSMutableOrderedSet anzuhängen.

- (void)addSubitemsObject:(SubItem *)value {
     NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
     [tempSet addObject:value];
     self.subitems = tempSet;
}

Durch die Neuzuweisung des Sets an self.subitems wird sichergestellt, dass die Will/DidChangeValue-Benachrichtigungen >gesendet werden.

Leelll, sind Sie sicher, dass nach einer solchen benutzerdefinierten Einrichtung von NSMutableOrderedSet Werte in diesem Satz gespeichert werden in der Datenbank korrekt von CoreData gespeichert werden? Ich habe das nicht überprüft, aber es sieht so aus, als ob CoreData nichts über NSOrderedSet weiß und NSSet als to-many Beziehungscontainer erwartet.

3voto

Ich bin gerade auf dieses Problem gestoßen und habe es mit einer viel einfacheren Implementierung als die anderen hier beschriebenen gelöst. Ich mache einfach Gebrauch von den Methoden, die auf NSManagedObject für den Umgang mit Beziehungen, wenn keine Unterklassen verwendet werden.

Eine Beispielimplementierung für das Einfügen einer Entität in eine NSOrderedSet Beziehung würde folgendermaßen aussehen:

- (void)addAddress:(Address *)address
{
    if ([self.addresses containsObject:address]) {
        return;
    }
    // Use NSManagedObject's methods for inserting an object
    [[self mutableOrderedSetValueForKey:@"addresses"] addObject:address];
}

Dies funktioniert einwandfrei und wurde von mir verwendet, bevor ich zu NSManagedObject Unterklassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X