Проблемы с KVO и Bindings при использовании моего собственного (не общего) объекта NSUserDefaults - PullRequest
3 голосов
/ 21 апреля 2009

Я подклассифицирую NSUserDefaults в моем приложении. Побочным эффектом этого является то, что я не могу использовать [NSUserDefaults sharedUserDefaults], мне нужен метод класса, чтобы обеспечить мой собственный статический объект по умолчанию. Это не было проблемой в коде, но теперь это становится непросто, поскольку я связываю пользовательский интерфейс настроек с привязками.

Общий NSUserDefaultsController использует общие значения по умолчанию, так что этого нет. Вместо этого я могу создать свой собственный контроллер по умолчанию в моем оконном контроллере, предоставить ему мой статический объект по умолчанию и подключить к нему мои привязки. Это не полностью работает, хотя. Когда я попытался использовать KVO на моем объекте по умолчанию, я не получил никаких уведомлений об изменениях. Я попробовал это снова с обычным объектом NSUserDefaults (не подклассом) и снова без уведомлений KVO. Подставляя в общий объект по умолчанию, KVO работает именно так, как я ожидал.

У кого-нибудь есть идеи, как заставить привязки и KVO работать, когда я не использую общие значения по умолчанию?

Ответы [ 4 ]

2 голосов
/ 09 мая 2009

Я всегда обертываю NSUserDefaults своим собственным классом, чтобы убедиться, что все работает как положено.

Рабочий процесс в основном выглядит следующим образом:

  1. Когда приложение запускается, считайте все необходимые записи NSUserDefaults в пользовательский класс. Этот пользовательский класс имеет свойство для каждого из параметров, и все объекты NSDictionary и NSArray являются изменяемыми, что позволяет вносить изменения.
  2. Любые элементы пользовательского интерфейса, которые вносят изменения в настройки, связаны со свойствами пользовательского класса.
  3. Изменения настроек сохраняются в NSUserDefaults по мере необходимости.

Я считаю, что эта инкапсуляция настроек приложения помогает снять все головные боли. Вместо того, чтобы напрямую работать с волшебной системой Apple NSUserDefaults, вы тратите свое время на взаимодействие с четко определенным и легко проверяемым пользовательским классом.

1 голос
/ 22 мая 2009

Я делал что-то похожее совсем недавно, и мне пока что везет. Я создаю стандартный подкласс NSObject (MYUserDefaults для аргумента). У него есть свойства для того, что я хочу (хост, имя пользователя и т. Д.). Некоторые переходят в NSUserDefaults, другие - в связку ключей или тому подобное. Он имеет стандартный +sharedUserDefaults метод синглтона. (*)

В владельце окна (NSWindowController или AppDelegate) я предоставляю -sharedUserDefaults. Затем я привязываю это к нужным настройкам с помощью простого пути к ключу (sharedUserDefaults.host). Обычно я не использую ключевые пути в привязках, потому что они часто запутывают вещи, но здесь я думаю, что все проясняется, принимая во внимание особый случай, когда нужно предотвратить создание дополнительной не-синглтоновой версии NIB.

(*) Ничего необычного " принудительный синглтон " (что также может решить вашу проблему). Я единственный, кто думает, что у Apple должна быть большая мигающая надпись «не используйте это, если вы не знаете, зачем она вам нужна, и не используйте ее в любом случае» на этом документе? Я нахожу этот код опасным для неопытных разработчиков. Половина объектов в последнем проекте, над которым я работал, была перегружена +allocWithZone:. Для меня это просто плохая форма - звонить +alloc и получать указатели на существующие объекты. Не ври мне, если это не является абсолютно необходимым.

1 голос
/ 21 апреля 2009

Документация дает ответ, я думаю. Метод init инициализирует новый экземпляр, но ничего не помещает в путь поиска. Если вы инициализируете свои собственные экземпляры, вам нужно вручную настроить домены, которые вы собираетесь использовать. Я предполагаю, что ваше приложение не работает, потому что значения, которые вы пытаетесь получить / установить, не существуют, потому что нет доменов для их сохранения.

В частности, посмотрите на метод addSuiteNamed: и константы NSUserDefaultsDomain. Вам нужно будет настроить их вручную, чтобы ваш подкласс или любой экземпляр NSUserDefaults, кроме standardUserDefaults, работал правильно.

0 голосов
/ 09 мая 2009

Поскольку я еще не нашел решения, я решил воспользоваться некоторыми советами, данными мне во время последнего собрания CocoaHeads Syracuse, и перейти на использование категорий вместо того, чтобы создавать подклассы NSUserDefaults. Не идеальное решение, но оно позволит мне преодолеть эту проблему и вернуться к работе.

...