9

Ho un modello semplice Foo che rappresenta una preferenza utente e incapsula un NSString e un NSNumber. Voglio memorizzare un array di Foo nelle impostazioni predefinite dell'utente in modo che rimangano tra i lanci dell'applicazione; e mi piacerebbe mostrarli in una vista tabella in modo che l'utente possa aggiungerli, rimuoverli e modificarli. La soluzione a questo mi è sembrata piuttosto semplice con i binding, ma per me è davvero impossibile lavorare.Visualizzazione tabella modificabile associata a NSArrayController associata a NSUserDefaultsController

All'avvio dell'applicazione, registro con NSUserDefaults un archivio con chiave di un array di Foo iniziali. Nel mio XIB ho un controller di array con il suo array di contenuti associato alla chiave del controller del controller di default utente values; con un percorso chiave di foos; 'Gestisce il contenuto come valore composto' controllato; e NSKeyedUnarchiveFromData come trasformatore di valore. La vista tabella viene quindi associata a turno al controller di array e alle colonne della tabella alle proprietà di Foo.

Questo funziona perfettamente quando Foo vengono aggiunti e rimossi dall'array: la chiave foos nei valori utente viene aggiornata per riflettere il nuovo contenuto dell'array. Il problema è che le modifiche alle proprietà di un individuo Foo non attivano in modo simile la matrice da riscrivere ai valori predefiniti dell'utente. Credo che la ragione di ciò sia discussa nella sezione "To-many Relationships" di "Registrazione delle chiavi dipendenti" nella Guida alla programmazione di osservazioni valore-chiave: le modifiche alla matrice stessa del controller dell'array sono osservate, ma le modifiche alle proprietà degli elementi contenuti non sono .

Nonostante riconosca questo come il problema, non posso per la vita di me capire cosa effettivamente fare per fare questo lavoro. Quando osservo una modifica su un quale oggetto è necessario informare e con quale messaggio tale che l'intero array viene riscritto nelle impostazioni predefinite dell'utente - NSUserDefaults, NSUserDefaultsController, NSArrayController? Vorrei che la documentazione di Apple avesse più di una breve descrizione di questo problema e fornito un codice di esempio per risolverlo: ho provato tutto e non riesco a trovare l'incantesimo magico.

Questo è simile a How to get notified of changes to models via an NSArrayController ma non riesco a fare il salto concettuale tra ciò che sta facendo con una vista personalizzata e l'uso di bind:toObject:withKeyPath:options:.

Grazie! :)

+0

Questo sembra davvero un lavoro per CoreData non NSUserDefaults. –

+0

Puoi elaborare? Il solo fatto di pensare alla quantità di documentazione che avrei bisogno di digerire per iniziare a implementare questa funzionalità con CoreData mi dà un problema. Dal punto di vista del modello di dati, quello che sto cercando di fare sembra estremamente semplice: data la complessità del CoreData sembra eccessivo. –

+0

Le impostazioni predefinite dell'utente sono per l'impostazione e si sta tentando di utilizzarla per memorizzare il modello di dati dal suono di esso. CoreData non è davvero molto difficile se si dispone di un modello di dati semplice. xcode ha modelli di progetto per questo che fondamentalmente fa tutto il setup per te. dovrebbe risolvere il problema che descrivi anche tu. –

risposta

0

Sono uno sviluppatore iOS, quindi perdonatemi se c'è qualche aspetto di ciò che mi manca a causa di iOS che non supporta i binding Cocoa.

Non saprei dirlo con certezza ma suona come se volessi ricevere una notifica quando qualsiasi proprietà di qualsiasi Foo viene modificata in modo da poter segnalare una modifica al tuo foos array e quindi fare in modo che NSUserDefaults aggiorni la matrice salvata. È corretto?

Supponendo di aver compreso lo scenario, e dato che, come hai detto, modificando l'array stesso (cioè aggiungendo/rimuovendo Foo all'interno di "foos" sta segnalando con successo il cambiamento, sembra ovvio che quello che devi fare è segnalare che foos è stato aggiornato ogni volta che una singola proprietà viene aggiornata

Per fare ciò, devi semplicemente sparare una notifica KVO quando cambia qualsiasi proprietà. Fondamentalmente potresti scavalcare i tuoi setter all'interno di Foo - per qualsiasi proprietà a cui tieni osservare e inviare una notifica lì

Ma come si fa?Il modello di solito per inviare una notifica KVO va come (per una proprietà chiamata openingBalance:

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

Ma nel tuo caso si desidera inviare una notifica che la proprietà 'foos' è cambiato e la sua non è una proprietà su Foo. Non c'è nulla che dice che la notifica deve essere solo per la proprietà specifica (o almeno nulla di cui sono a conoscenza). Ma probabilmente non vuoi che Foo sappia che è composto all'interno di una proprietà 'foos' da qualche parte Altrimenti

Quindi, che ne dici di utilizzare una NSNotification semplice? Creare un metodo generico per attivare una notifica "Foo" aggiornata all'interno di Foo - sottoclassi i setter e quindi attivare questa notifica ogni volta che si modifica una proprietà Foo.

A sua volta, all'interno dell'oggetto che possiede 'foos' iscriversi a questa notifica e aggiornare direttamente NSUserDefaults o, da lì, attivare le notifiche KVO per 'foos' lì.