3

我在我的应用程序中继承 NSUserDefaults。这样做的副作用是我不能使用[NSUserDefaults sharedUserDefaults],我必须有一个类方法来提供我自己的静态默认对象。这在代码中不是问题,但现在证明我正在将首选项 UI 与绑定连接起来很棘手。

共享的 NSUserDefaultsController 使用共享的默认值,所以就不行了。相反,我可以在我的窗口控制器中创建我自己的默认控制器,为它提供我的静态默认对象,并将我的绑定连接到它。但是,这并不完全有效。当我尝试在我的默认对象上使用 KVO 时,我没有收到任何更改通知。我使用常规的 NSUserDefaults 对象(不是子类)再次尝试了此操作,并且再次没有 KVO 通知。替换为共享默认对象,KVO 完全按照我的预期工作。

当我不使用共享默认值时,是否有人对我如何让绑定和 KVO 工作有任何想法?

4

4 回答 4

2

我总是用我自己的自定义类来包装 NSUserDefaults 的东西,以确保一切都按预期工作。

工作流程基本上是这样的:

  1. 当应用程序启动时,将所有必需的 NSUserDefaults 条目读入自定义类。这个自定义类的每个设置都有一个属性,并且所有 NSDictionary 和 NSArray 对象都是可变的,因此可以进行更改。
  2. 任何对设置进行更改的用户界面元素都绑定到自定义类的属性
  3. 对设置的更改会根据需要保存到 NSUserDefaults。

我发现应用程序设置的这种封装有助于消除所有的麻烦。您无需直接处理 Apple 神奇的 NSUserDefaults 系统,而是将时间花在与定义明确且易于测试的自定义类进行交互上。

于 2009-05-08T20:32:49.613 回答
1

我认为,文档提供了答案。该init方法初始化一个新实例,但不会在搜索路径中放置任何内容。如果您要初始化自己的实例,则需要手动设置您打算使用的域。我的猜测是您的应用程序无法正常工作,因为您尝试获取/设置的值不存在,因为没有域可以保存它们。

特别是,查看addSuiteNamed:方法和NSUserDefaultsDomain常量。您需要手动设置这些以使您的子类或NSUserDefaults除 之外的任何实例standardUserDefaults正常工作。

于 2009-04-21T16:12:46.657 回答
1

我最近一直在做类似的事情,到目前为止我的运气还不错。我创建了一个标准的 NSObject 子类(参数为 MYUserDefaults)。它具有我想要的东西的属性(主机、用户名等)。有些转到 NSUserDefaults,有些转到钥匙串等。它有一个标准的+sharedUserDefaults单例方法。(*)

在窗口所有者(NSWindowController 或 AppDelegate)中,我提供了一个-sharedUserDefaults. 然后我通过一个简单的密钥路径(sharedUserDefaults.host)将其绑定到我想要的设置。我通常避免在绑定中使用键路径,因为它们经常混淆事物,但在这里我认为它可以在处理需要防止 NIB 创建额外的非单例版本的特殊情况时保持一切清晰。

(*) 没有花哨的“强制单身”的东西(这也可能解决你的问题)。我是唯一一个认为 Apple 应该在这个文档上大闪“除非你知道为什么需要它,否则不要使用它,否则不要使用它”的人?我发现让没有经验的开发人员看到的代码很危险。我上一个项目中的一半对象已经+allocWithZone:超载。对我来说,调用+alloc并获取指向现有对象的指针只是一种糟糕的形式。除非绝对必要,否则不要对我撒谎。

于 2009-05-21T21:30:35.247 回答
0

由于我还没有找到解决方案,所以我决定接受在上次 CocoaHeads Syracuse 会议上给我的一些建议,并改用使用类别而不是继承 NSUserDefaults。不是一个完美的解决方案,但它会让我克服这个问题并重新开始工作。

于 2009-05-08T20:26:28.130 回答