【问题标题】:KVO and Bindings problems using my own (not the shared) NSUserDefaults object使用我自己的(不是共享的)NSUserDefaults 对象的 KVO 和绑定问题
【发布时间】:2009-04-21 13:17:03
【问题描述】:

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

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

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

【问题讨论】:

    标签: objective-c cocoa cocoa-bindings nsuserdefaults key-value-observing


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 文档在这个主题上有点混乱,但它确实说 init 添加了应用程序和注册域。我还注意到一个 init'ed 对象在 10.5 中包含全局域,但在 10.4 中不包含,因此文档也可能稍微过时了。无论如何,问题仅限于 KVO——我的子类对象在代码中使用时可以保存和读取首选项,所以除非我遗漏了一些东西,否则搜索域似乎没有任何问题。不过感谢您的回复!
      【解决方案3】:

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

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

      (*) 没有花哨的“forced singleton”东西(这也可能解决你的问题)。我是唯一一个认为Apple应该在这个文档上大闪“除非你知道为什么需要它,否则不要使用它,然后无论如何都不要使用它”的大闪烁标志?我发现让没有经验的开发人员看到的代码很危险。在我参与的上一个项目中,有一半的对象有 +allocWithZone: 重载。对我来说,调用+alloc 并获取指向现有对象的指针是一种糟糕的形式。除非绝对必要,否则不要骗我。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2011-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多