9

Mam prosty model Foo, który reprezentuje preferencje użytkownika i zawiera w sobie kod NSString i NSNumber. Chcę przechowywać tablicę o wartości Foo w domyślnych ustawieniach użytkownika, aby pozostały między uruchomieniami aplikacji; i chciałbym wyświetlić je w widoku tabeli, aby użytkownik mógł je dodawać, usuwać i edytować. Rozwiązanie tego problemu wydawało się proste z wiązaniami, ale okazało się to niemożliwe, abym faktycznie pracował.Edytowalny widok tabeli powiązany z NSArrayController powiązany z NSUserDefaultsController

Po uruchomieniu mojej aplikacji rejestruję się w NSUserDefaults archiwum z kluczem w postaci tablicy początkowej Foo. W moim XIB mam kontroler tablicowy z tablicą treści związaną z kluczem kontrolera współdzielonego użytkownika domyślnego kontrolera values; z kluczową ścieżką foos; "Sprawdzanie zawartości jako wartości złożonej" zaznaczone; i NSKeyedUnarchiveFromData jako transformator wartości. Widok tabeli jest następnie powiązany z kontrolerem macierzy i kolumnami tabeli z właściwościami Foo.

Działa to doskonale, gdy Foo są dodawane i usuwane z tablicy - klucz foos w domyślnych ustawieniach użytkownika jest aktualizowany w celu odzwierciedlenia nowej zawartości tablicy. Problem polega na tym, że zmiany właściwości indywidualnych Foo nie powodują podobnego zapisu tablicy z powrotem do domyślnych ustawień użytkownika. Sądzę, że przyczyna tego jest omawiana w sekcji "To-many Relationships" w sekcji "Rejestrowanie kluczy zależnych" w Przewodniku programowania obserwacji wartości klucza, obserwowane są zmiany w samej tablicy kontrolera tablicowego, ale zmiany właściwości zawartych elementów nie są .

Pomimo uznania tego problemu za niemożliwy do spełnienia przeze mnie, muszę się dowiedzieć, co należy zrobić, aby to zadziałało. Kiedy obserwuję zmianę na obiekcie Foo, jaki obiekt muszę podać i jaki komunikat tak, aby cała tablica została zapisana z powrotem do ustawień domyślnych użytkownika - NSUserDefaults, NSUserDefaultsController, NSArrayController? Chciałbym, żeby dokumentacja Apple miała więcej niż pobieżną wzmiankę o tym problemie i dostarczyła jakiś rzeczywisty przykładowy kod, żeby go rozwiązać. Próbowałem wszystkiego i nie mogę znaleźć magicznego zaklęcia.

Jest to podobne do How to get notified of changes to models via an NSArrayController, ale nie mogę dokonać konceptualnego skoku między tym, co robi z widokiem niestandardowym a użyciem bind:toObject:withKeyPath:options:.

Dzięki! :)

+0

To naprawdę brzmi jak zadanie dla CoreData, a nie NSUserDefaults. –

+0

Czy możesz opracować? Samo myślenie o ilości dokumentacji, którą muszę przetrawić, aby zacząć ją wdrażać z CoreData, sprawia mi ból głowy. Z perspektywy modelu danych to, co próbuję zrobić, wydaje się być bardzo proste - biorąc pod uwagę złożoność CoreData, wydaje się, że to przesada. –

+0

Ustawienia domyślne dla użytkownika dotyczą ustawień i próbujesz go użyć do przechowywania modelu danych z jego dźwiękiem. CoreData naprawdę nie jest bardzo trudne, jeśli naprawdę masz prosty model danych. xcode ma szablony projektów, które w zasadzie wykonują całą konfigurację dla ciebie. powinien rozwiązać problem, który opisujesz. –

Odpowiedz

0

Jestem programistą iOS, więc wybacz mi, jeśli jest jakiś aspekt tego, czego mi brakuje z powodu iOS nie obsługujących wiązań Cocoa.

Nie mogłem powiedzieć na pewno, ale brzmi to tak, jakbyś chciał otrzymać powiadomienie, gdy jakakolwiek właściwość dowolnego Foo zostanie zmodyfikowana, tak abyś mógł zasygnalizować zmianę w tablicy foos, a tym samym odświeżyć zapisaną tablicę przez NSUserDefaults. Czy to jest poprawne?

Zakładając, że rozumiem scenariusz, i biorąc pod uwagę, że, jak powiedziałeś, modyfikowanie samej tablicy (tj. Dodawanie/usuwanie Foo w "foos" z powodzeniem sygnalizuje zmianę, wydaje się oczywiste, że to co musisz zrobić, to zasygnalizować te informacje zostały zaktualizowane za każdym razem, gdy aktualizowana jest pojedyncza właściwość:

Aby to zrobić, po prostu trzeba zwolnić powiadomienie KVO, gdy zmieni się jakakolwiek właściwość.Zasadniczo można przesłonić ustawiające w Foo - dla wszelkich właściwości, na których zależy obserwując i wysyłając powiadomienie

Ale jak ty to robisz?Zazwyczaj wzór wysłać zgłoszenie KVO idzie tak (na właściwość o nazwie openingBalance:

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

Ale w przypadku, gdy chcesz wysłać powiadomienie, że właściwość „foos” uległa zmianie i nie jest to właściwość na Foo. Nic nie mówi, że powiadomienie musi dotyczyć tylko konkretnej nieruchomości (lub przynajmniej niczego, o czym jestem świadomy), ale prawdopodobnie nie chcesz, aby Foo wiedział, że jest ona skomponowana wewnątrz obiektu "foos" gdzieś w przeciwnym razie:

A więc, po prostu za pomocą prostego NSNotification? Utwórz ogólną metodę wypalania "Foo" zaktualizowanego Powiadomienia wewnątrz Foo - podklasuj swoje setery, a następnie uruchom powiadomienie za każdym razem, gdy modyfikujesz własność Foo.

Z kolei w twoim obiekcie będącym właścicielem 'foos' zasubskrybuj to powiadomienie i albo bezpośrednio zaktualizuj NSUserDefaults, albo stamtąd zwolnij swoje powiadomienia KVO o "foos" tam.

Powiązane problemy