【问题标题】:Editable table view bound to NSArrayController bound to NSUserDefaultsController绑定到 NSArrayController 的可编辑表视图绑定到 NSUserDefaultsController
【发布时间】:2013-05-10 16:08:54
【问题描述】:

我有一个简单的模型Foo,它代表用户偏好并封装了NSStringNSNumber。我想在用户默认值中存储Foo 的数组,以便它们在应用程序启动之间保持不变;我想在表格视图中显示它们,以便用户可以添加、删除和编辑它们。使用绑定的解决方案似乎很简单,但事实证明我无法真正开始工作。

当我的应用程序启动时,我向NSUserDefaults 注册了一个包含初始Foo 数组的键控存档。在我的 XIB 中,我有一个数组控制器,其内容数组绑定到共享用户默认控制器的 values 控制器键;密钥路径为foos;选中“将内容作为复合值处理”;和NSKeyedUnarchiveFromData 作为值转换器。然后表格视图依次绑定到数组控制器,表格的列绑定到Foo 的属性。

Foo 从数组中添加和删除时,这非常有效——用户默认值中的foos 键被更新以反映数组的新内容。问题在于,对单个 Foo 的属性的更改不会同样触发将数组写回用户默认值。我相信其原因在 Key-Value Observing Programming Guide 中的“Registering Dependent Keys”的“To-many Relationships”部分中进行了讨论:观察到对数组控制器的数组本身的更改,但对所包含元素的属性的更改是不。

尽管认识到这是一个问题,但我终其一生都无法弄清楚要真正做什么才能完成这项工作。当我观察到Foo 的更改时,我需要通知什么对象以及使用什么消息将整个数组写回用户默认值—NSUserDefaultsNSUserDefaultsControllerNSArrayController?我希望 Apple 文档不仅仅是粗略地提到这个问题,并提供了一些实际的示例代码来解决它——我已经尝试了所有方法,但我找不到神奇的咒语。

这类似于How to get notified of changes to models via an NSArrayController,但我无法在他使用自定义视图所做的事情和使用bind:toObject:withKeyPath:options: 之间做出概念上的飞跃。

谢谢! :)

【问题讨论】:

  • 这听起来确实像是 CoreData 而不是 NSUserDefaults 的工作。
  • 您能详细说明一下吗?想想我需要消化大量的文档才能开始使用 CoreData 实现它,这让我很头疼。从数据模型的角度来看,我正在尝试做的事情似乎非常简单——考虑到 CoreData 的复杂性,这里似乎有点矫枉过正。
  • 好吧,用户默认值是用于设置的,您正在尝试使用它来存储您的数据模型。如果您确实有一个简单的数据模型,CoreData 确实不是很困难。 xcode 有它的项目模板,基本上可以为您完成所有设置。它应该也可以解决您描述的问题。
  • 我必须同意布拉德的观点。 CoreData 确实是要走的路,它确实没有看起来那么难(所有数据库系统都这么简单吗)。

标签: objective-c cocoa nsuserdefaults cocoa-bindings nsarraycontroller


【解决方案1】:

我是一名 iOS 开发人员,如果由于 iOS 不支持 Cocoa 绑定而遗漏了这方面的某些方面,请原谅我。

我无法确定,但听起来好像您想在任何 Foo 的任何属性被修改时收到通知,以便您可以发出更改 foos 数组的信号,从而让 NSUserDefaults 刷新保存的数组。对吗?

假设我了解这种情况,并且正如您所说,修改数组本身(即在 'foos' 中添加/删除 Foo 已成功发出更改信号,显然您需要做的就是发出信号每次更新单个属性时,foos 都会更新。

为此,您只需在任何属性更改时触发 KVO 通知。基本上,您将覆盖 Foo 中的设置器 - 对于您关心观察的任何属性。并在那里发送通知。

但是你是怎么做到的呢?发送 KVO 通知的常用模式如下(对于名为 openingBalance 的属性:

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

但在您的情况下,您想发送属性“foos”已更改的通知。它不是 Foo 的属性。没有什么说通知必须只针对特定属性(或者至少我不知道)。但是,您可能不希望 Foo 知道它是在其他地方的 'foos' 属性中组成的。

那么,直接使用 NSNotification 怎么样?创建一个通用方法来触发 Foo 内的“Foo”更新通知 - 子类化您的设置器,然后在您修改 Foo 属性时触发此通知。

反过来,在拥有 'foos' 的对象内部订阅此通知,并直接更新 NSUserDefaults 或从那里触发 'foos' 的 KVO 通知。

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    相关资源
    最近更新 更多