9

Ich habe ein einfaches Modell Foo, das eine Benutzerpräferenz darstellt und eine NSString und eine NSNumber einkapselt. Ich möchte ein Array von Foo in Benutzerstandards speichern, so dass sie zwischen den Starts der Anwendung bestehen bleiben; und ich möchte sie in einer Tabellenansicht anzeigen, sodass der Benutzer sie hinzufügen, entfernen und bearbeiten kann. Die Lösung dafür schien mit Bindings ziemlich einfach zu sein, aber es ist mir unmöglich, tatsächlich zu arbeiten.Editierbare Tabellenansicht an NSArrayController gebunden an NSUserDefaultsController

Wenn meine Anwendung startet, registriere ich mit NSUserDefaults ein verschlüsseltes Archiv eines Arrays von Foo 's. In meinem XIB habe ich einen Array-Controller, dessen Inhalts-Array an den Controller-Schlüssel values des freigegebenen Benutzer-Standard-Controllers gebunden ist; mit einem Schlüsselpfad von foos; 'Behandelt Inhalt als Verbindungswert' markiert; und NSKeyedUnarchiveFromData als der Wertwandler. Die Tabellenansicht wird dann wiederum an den Array-Controller und die Spalten der Tabelle an die Eigenschaften Foo gebunden.

Dies funktioniert einwandfrei, wenn Foo hinzugefügt und aus dem Array entfernt werden - der Schlüssel foos in Benutzerstandards wird aktualisiert, um den neuen Inhalt des Arrays widerzuspiegeln. Das Problem besteht darin, dass Änderungen an den Eigenschaften einer Person Foo nicht in ähnlicher Weise auslösen, dass das Array in Benutzerstandards zurückgeschrieben wird. Ich glaube, der Grund dafür wird im Abschnitt "Registrieren von abhängigen Schlüsseln" im Schlüsselwertbeobachtungs-Programmierleitfaden unter "To-many Relationships" diskutiert: Änderungen am Array-Controller des Array-Controllers selbst werden beobachtet, aber nicht an den Eigenschaften der enthaltenen Elemente .

Obwohl ich dies als das Problem anerkenne, kann ich nicht für das Leben von mir herausfinden, was ich tun soll, um das funktionieren zu lassen. Wenn ich eine Änderung an einem Foo beobachte, welches Objekt muss ich informieren und mit welcher Nachricht, so dass das gesamte Array zurück auf Benutzerstandards geschrieben wird - NSUserDefaults, NSUserDefaultsController, NSArrayController? Ich wünschte, die Apple-Dokumentation hätte dieses Problem mehr als nur oberflächlich erwähnt und einige tatsächliche Beispielcodes zur Verfügung gestellt, um es zu lösen - ich habe alles versucht und kann die magische Beschwörung nicht finden.

Dies ist ähnlich wie How to get notified of changes to models via an NSArrayController, aber ich kann nicht den konzeptionellen Sprung zwischen dem, was er mit einer benutzerdefinierten Ansicht macht und der Verwendung von bind:toObject:withKeyPath:options: machen.

Danke! :)

+0

Das klingt wirklich wie ein Job für CoreData nicht NSUserDefaults. –

+0

Können Sie es ausarbeiten? Wenn ich nur über die Menge an Dokumentation nachdenke, die ich verdauen müsste, um diese sogar mit CoreData zu implementieren, bereitet mir das Kopfschmerzen. Aus der Sicht des Datenmodells scheint das, was ich versuche, extrem einfach zu sein - angesichts der Komplexität von CoreData erscheint es hier als Overkill. –

+0

Nun Benutzer Standardeinstellungen sind für die Einstellung und Sie versuchen, es zu verwenden, um Ihr Datenmodell aus dem Sound davon zu speichern. CoreData ist wirklich nicht sehr schwierig, wenn Sie wirklich ein einfaches Datenmodell haben. xcode hat Projektvorlagen für Sie, die im Prinzip alle Einstellungen für Sie vornehmen. Es sollte das von Ihnen beschriebene Problem lösen. –

Antwort

0

Ich bin ein iOS-Entwickler, also vergib mir, wenn es einen Aspekt davon gibt, den ich vermisse, weil iOS keine Cocoa-Bindungen unterstützt.

Ich konnte nicht sicher sagen, aber es klingt, als ob Sie eine Benachrichtigung erhalten möchten, wenn eine Eigenschaft von einem Foo geändert wird, so dass Sie eine Änderung an Ihrem Foos-Array signalisieren können und NSUserDefaults das gespeicherte Array aktualisieren. Ist das korrekt?

Angenommen, ich verstehe das Szenario und vorausgesetzt, dass, wie Sie gesagt haben, das Ändern des Arrays selbst (dh das Hinzufügen/Entfernen von Foo in 'foos') erfolgreich die Änderung signalisiert, ist es offensichtlich, dass Sie signalisieren müssen diese foos wurde aktualisiert, sobald eine einzelne Eigenschaft aktualisiert wird

Um dies zu tun, müssen Sie nur eine KVO-Benachrichtigung auslösen, wenn sich eine Eigenschaft ändert.Im Grunde würden Sie Ihre Setter in Foo überschreiben - für alle Eigenschaften, die Sie interessieren Beobachten Sie und senden Sie eine Benachrichtigung dort.

Aber wie machst du das?Das übliche Muster eine KVO-Benachrichtigung senden geht so (für eine Eigenschaft namens openingBalance:

[self willChangeValueForKey:@"openingBalance"]; 
_openingBalance = theBalance; 
[self didChangeValueForKey:@"openingBalance"]; 

Aber in Ihrem Fall Sie eine Benachrichtigung senden, dass die Eigenschaft ‚Foos‘ hat sich verändert und es ist nicht eine Eigenschaft auf Foo. Es gibt nichts, was sagt, dass die Benachrichtigung nur für die spezifische Eigenschaft sein muss (oder zumindest nichts, was mir bekannt ist.) Aber wahrscheinlich wollen Sie nicht, dass ein Foo weiß, dass es irgendwo in einer "foos" -Eigenschaft verfasst ist sonst.

Also, wie wäre es nur mit einer geraden NSNotification? Erstellen Sie eine generische Methode, um eine 'Foo' aktualisierte Benachrichtigung innerhalb Foo - Unterklasse Ihre Setter, und dann diese Benachrichtigung auslösen, wann immer Sie eine Foo-Eigenschaft ändern.

Im Gegenzug abonnieren Sie in Ihrem Objekt, das 'foos' besitzt, diese Benachrichtigung und entweder NSUserDefaults direkt aktualisieren oder von dort aus Ihre KVO-Benachrichtigungen für 'foos' dort auslösen.

Verwandte Themen