2009-12-07 19 views
7

Ich habe Probleme, einen Core-Daten gesichert NSArrayController ordnungsgemäß in meinem Code zu arbeiten. Unten ist mein Code:NSArrayController Initialisierung

pageArrayController = [[NSArrayController alloc] initWithContent:nil]; 
    [pageArrayController setManagedObjectContext:[self managedObjectContext]]; 
    [pageArrayController setEntityName:@"Page"]; 
    [pageArrayController setAvoidsEmptySelection:YES]; 
    [pageArrayController setPreservesSelection:YES]; 
    [pageArrayController setSelectsInsertedObjects:YES]; 
    [pageArrayController setClearsFilterPredicateOnInsertion:YES]; 
    [pageArrayController setEditable:YES]; 
    [pageArrayController setAutomaticallyPreparesContent:YES]; 
    [pageArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]]; 
    BOOL result = [pageArrayController setSelectionIndex:0]; 

Als ich setSelectionIndex zu nennen versuchen :, es JA zurückgibt, was darauf hinweist, dass die Auswahl erfolgreich geändert wurde. Alle nachfolgenden getSelectionIndex-Aufrufe an das pageArrayController-Objekt geben jedoch NSNotFound zurück.

Was ich nicht verstehe, ist, dass, wenn ich den NSArrayController in eine NIB einfüge und erlaube, dass die NIB-Datei die Initialisierung durchführt (mit allen gleichen Attributen in Interface Builder), funktioniert der NSArrayController korrekt.

Warum gibt es einen Unterschied im Verhalten? Initialisiert die NIB-Datei diese Arten von Objekten auf eine spezielle Art und Weise? Ist meine Initialisierung des NSArrayControllers falsch?

Jede Hilfe wird geschätzt. Vielen Dank.

+0

Es gibt keine "-getSelectionIndex" -Methode. Hast du eine solche Methode selbst geschrieben oder etwas anderes genannt? –

+0

Ich meinte -selectionIndex. –

Antwort

14

Ja, nibs initialisieren Objekte auf eine spezielle Art und manchmal kann es schwierig sein, herauszufinden, wie man das repliziert. Ich hatte auch damit zu kämpfen und fand schließlich die Antwort in Apples Core Data Programming Guide >> Core Data und Cooca Bindings >>Automatically Prepares Content Flag (Danke an Dave Fernandes auf der Cocoa Dev Liste). Die Antwort lautet: Wenn Sie einen Arraycontroller mit Null-Inhalt initialisieren, müssen Sie ebenfalls einen Abruf durchführen.

BOOL result; 
NSArrayController *pageArrayController = [[NSArrayController alloc] initWithContent:nil]; 
[pageArrayController setManagedObjectContext:[self managedObjectContext]]; 
[pageArrayController setEntityName:@"Page"]; 
NSError *error; 
if ([pageArrayController fetchWithRequest:nil merge:YES error:&error] == NO) 
    result = NO; 
else 
{ 
    //do all that other pageArrayController configuration stuff 
    result = [pageArrayController setSelectionIndex:0]; 
} 

BTW, [NSSortDescriptor sortDescriptorWithKey: @ "index" aufsteigend: JA]] wirft eine Warnung.

+0

Außerdem bedeutet Ihre Verwendung von [self managedObjectContext], dass Sie Ihre pageArrayController-Methoden zu appDelegate hinzugefügt haben. Dies wird nicht als gute Praxis angesehen.Sie sollten wirklich in die Erstellung eines separaten Seitencontrollerobjekts schauen (und Objekte modellieren und anzeigen, um das MVC-Muster zu implementieren), das sich um die gesamte Seitenfunktionalität Ihrer Anwendung kümmert. Die Seitencontroller- oder Seitenmodellobjekte können [[NSApp delegate] managedObjectContext] bei Bedarf aufrufen. –

+0

Danke für diese Lösung, es funktioniert perfekt. Meine App-Struktur ist jetzt viel besser, da ich diese Array-Controller im Code erstellen kann, anstatt auf Nibs angewiesen zu sein. –

+0

Sie mein Freund, sind eine Legende! Ich habe tagelang versucht, herauszufinden, warum mein Array-Controller nicht aktualisiert wurde, als neue Daten von iCloud in meinen Core Data Store kamen. Jetzt funktioniert es perfekt. Vielen Dank. – Fin

0

Soweit warum im Verhalten ein Unterschied da sein kann:

  1. Nib Dateien speichern serialisierte Objekte mit NSCoder.
  2. Wahrscheinlich verwenden Sie die Bindung auf der IB-Seite der Dinge, wo Sie in Ihrem Code den Kontext des verwalteten Objekts direkt setzen, indem Sie eine set-Methode verwenden.

Vielleicht könnten Sie so etwas wie die folgenden in Ihrem Code versuchen:

[pageArrayController bind:@"managedObjectContext" 
       toObject:self 
       withKeyPath:@"managedObjectContext" 
        options:nil]; 

Ich habe Xcode nicht in der Nähe sonst würde ich irgendwas versuchen. Hoffentlich gibt dies dir einige Hinweise, um dich in die richtige Richtung zu bringen.

0

Von wo aus erstellen/konfigurieren Sie Ihren Array-Controller? Der Core Data-Stack ist möglicherweise noch nicht bereit, daher kann Ihr Aufruf von [self managedObjectContext] möglicherweise nil zurückgeben.

Auch, warum erstellen Sie es programmgesteuert, wenn Sie es einfach mit Interface Builder tun können? Das Tool ist da und funktioniert gut (und eliminiert viele mögliche Codierungsfehler). Wenn Sie also keinen guten Grund haben, es nicht zu verwenden, tun Sie sich selbst keinen Gefallen.

+0

Nun, in meinem Fall erstelle ich NSArrayController in Code, als wenn IB verwendet wird, binded Daten in NSArrayController sind noch nicht geladen in 'awakeFromNib' Methode. Wissen Sie, wie das Problem in IB gelöst werden kann? – xyz

Verwandte Themen