Frage

Update: Dieser Thread identifiziert einen Fehler in NSCollectionView wenn die dargestellten Objekte der Sammlungsansicht NSManagedObjects sind. Der Fehler wird ausgelöst, wie folgt:

(a) Löschen von Objekten aus dem NSArrayController Führen Sie (b) speichern auf die damit verbundene NSManagedObjectContext jederzeit nach dem Löschen und vor dem NSCollectionView beendet seine Animation.

Diese Projekte auf Github demonstrieren das Problem.

https://github.com/artifacts/NSCollectionViewCoreDataBug https://github.com/iracooke/CoreDataCollectionViewCrashing

Original Frage unter

Ich habe einen NSCollectionView Setup mit seinem Inhalt Bindung an arrangedObjects eines NSArrayController von Kern-Dateneinheiten gebunden. In meiner Sammlung Artikel Ansicht (der Prototyp für die NSCollectionView Ansicht) habe ich mehrere Kontrollen über representedObject meiner Kollektion Artikel gebunden zu meinen Kern-Dateneinheiten.

Für den größten Teil funktioniert dies OK.

Ich begegne eine objc_exception wenn ich versuche, Einheiten von meinem Arraycontroller zu löschen. Ich lösche diese Unternehmen, die lediglich durch den Aufruf;

[myArrayController removeObject:managedObjectToDelete];

Leider, wenn ich das tue ich häufig bekomme einen Fehler „Coredata könnte einen Fehler nicht erfüllen“ .. mit der verantwortlichen Stelle als eine der Einrichtungen, die von den NSArrayController verwaltet werden.

Die Untersuchung des Call-Stack, wenn die Ausnahme ausgelöst wird offenbart, dass der Crash entsteht, wenn die NSCollectionView seine _endOfAnimation Methode erhält. Dies wiederum initiiert andere Methoden zu tun mit freibleibend (wahrscheinlich von Eigenschaften meiner Einheit mit den Kontrollen in meiner Sicht).

Ein weiteres Bit an Informationen ist, dass die Entity arbeite ich mit keine Beziehungen zu anderen Entitäten in meinem Modell hat.

Es sieht für mich, als ob das folgende Problem auftritt;

  • Wenn ich Objekte aus meinen NSArrayController lösche sie sind wiederum aus dem Kontext gelöscht.
  • Nach dem Löschen aus dem Kontext werden die Objekte in Fehler einge
  • Die NSCollectionView hat Verweise auf die Objekte beibehalten (jetzt Fehler). Es wird versucht, sie am Ende ihrer Animation zu bereinigen (unbinding usw.).
  • Wenn NSCollectionView versucht zu bereinigen Bindungen an das Objekt bewirkt, dass es Kerndaten einen Fehler, versuchen, auf dem Objekt zu schießen (Hoffnung habe ich meine Terminologie genau dort). Dies verursacht einen Fehler, da das Objekt noch nicht auf der Festplatte gespeichert.

Die einzige Art, wie ich mich vorstellen kann dies zu verhindern, ist es, die Objekte im Speicher zu bestehen (durch sie zu speichern) vor dem Löschen. Dies funktioniert, aber nur in einer hackish Art und Weise, da ich brauche, um sicherzustellen, dass eine Runde Löschung abgeschlossen ist, bevor erneut zu speichern ... und da der Fehler auftritt, während eine Animation .. nach einiger Verzögerung .. und zwei speichert nacheinander würde führen im gleichen Fehler auftritt wieder.

Heißt das, dass ich nicht eine Core-Data NSArrayController verwendet wird, kann gesichert eine NSCollectionView zu füllen? Wenn nicht, was mache ich falsch? Gibt es einen besseren Weg, um dieses Problem?

War es hilfreich?

Lösung

Eine direkte noch langweilige Antwort: kann ich bestätigen, dass ein Core Data gesichert NSArrayController eine NSCollectionView bevölkern können, mit verschiedenen GUI-Objekte in der Sammlung NSView Element gebunden an die erzeugte „Collection View Item“ und verschiedene Kerndaten zu beziehen Objekte entlang der Pfad. Programmatische Löschen (und Nachbestellung) Elemente der NSArrayController Werke (mit Animation kostenlos).

Vielleicht haben einige Bindungen oder andere Abhängigkeiten in Ihrer Sammlung Ansicht das Problem verursachen? Oder ein Threading-Problem mit dem Managed Object Context (s)?

Andere Tipps

Sie können dieses Problem umgehen, indem das Hinzufügen eine (assign) Immobilie zu Ihrer CollectionItem, die Punkte an dem entsprechenden Arraycontroller.

Diese Eigenschaft kann in gesetzt werden. - [YourNSCollectionViewSubClass newItemWithRepresentedObject:]

Dann können Sie arrangedObjects in jedem Element beobachten. Wenn sie sich ändert und item.representedObject nicht in arrangedObjects mehr enthalten ist, Sie setzen item.representedObject null. In meinen Tests (10.6.8), dies löst die Bindung Bereinigung vor Coredata stellt sich die Objekte in Fehler. (Meine Objekte haben Beziehungen und die Positionssicht hat Bindungen in ihnen).

btw: Dieses Problem beschränkt sich nicht während der Animation zu speichern, Undo / Redo / save Kombinationen können es auch auslösen.

Ich war für einen guten Platz suchen, um die Beobachtung in dem Artikel zu starten, aber die einzige, die ich herauskam, war copyWithZone: was ich vermeiden wollte. (-AwakeFromNib ist nur für den ersten Punkt genannt wird -Blick zu früh).

Deshalb I (ungern) beschlossen, die Beobachtung in -newItemWithRepresentedObject zu starten: und es in dem -dealloc Stück zu stoppen.

Sie sollten auch für alle Kontrollen achten oder andere durch Objekte ausgelöste Aktionen in der Artikelansicht - durch schnelles Klicken ich Nachrichten an deallokierten Objekte dazu führen könnten, vermutlich, weil die noch reagierenden Tasten, wo sie unter der Maus Animieren. Meine Lösung ist es, die Kontrollen zu deaktivieren, wenn representedObject auf Null zu setzen. YMMV.

Hier ist mein Beobachter Code:

    - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if( object == self.arrayController && [keyPath isEqualToString: @"arrangedObjects"] ) {
        if( NO == [self.arrayController.arrangedObjects containsObject: self.representedObject] ) {
            self.representedObject = nil;

            for(NSView *subview in [self.view subviews]) {
                if( [subview isKindOfClass: [NSControl class]] ) {
                    [(NSControl *)subview setEnabled: NO];
                }
            }
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject: object change:change context:context];
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top