4

我正在阅读关于Objective-c的一本书并了解撤消管理器。这个概念看起来很简单,但提供的例子似乎过于复杂。基本上,我有一个表视图连接到一个NSArrayController,我添加或删除人员到一个数组,我可以编辑他们的名字和东西。因为该示例使用NSArrayController和绑定,所以添加和删除是自动的,并且所有的编辑都是自动的。Objective-C撤消管理器问题

要使用撤消管理器,从我的理解,我需要实现我自己的方法来添加/删除/编辑。

我实现做了添加和删除,并得到应有的关键值编码自动调用这些方法:

- (void)removeObjectFromEmployeesAtIndex:(int)index; 
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index; 

然后进行编辑,我必须注册类作为观察员,观察变化编辑:

- (void)changeKeyPath:(NSString *)keyPath 
      ofObject:(id)obj 
       toValue:(id)newValue 

这里是我的问题:

  1. 为什么我公顷有做这么多?我的理解是,使用NSArrayController和绑定应该使添加/删除/编辑项目变得更容易和更自动化。但是,如果我必须手动实现所有这些方法,只需添加撤销支持,为什么要使用NSArrayController或绑定呢?

  2. 背后发生了什么?在Interface Builder中,添加按钮连接到NSArrayController上的add方法。那么我的insertObject方法如何被调用?我知道这是通过关键的值编码,但是什么使得NSArrayController的add方法被重写仅仅是b/c我的文档实现了这个方法?

  3. 该解决方案是不对称的。我使用一个概念来处理撤消添加/删除以及另一个概念来处理撤消编辑。我不能只观察对数组的更改吗?我想这会使观察值关键字方法复杂化,但是这会更有意义吗?

+0

你使用的是核心数据? – 2011-06-12 18:35:42

+0

不,我还没有了解到这一点,但 – JPC 2011-06-12 22:59:15

+1

你通过在Core Data之前学习这一点而节省了很多痛苦;那么它会变得更有意义。我可以提供的一点建议是,你可以在Cocoa/Xcode中找到非常方便使用的东西,但是你经常需要解决。一个具体的例子是使用IB来创建GUI--做,复杂的事情会变得无用(对于动画等),并且你必须得到幕后(IB在CoreData为你的问题做了改进)。似乎你现在已经看到了其中一种情况。我的观点是:如果你觉得自己在做一些艰难的事情,它可能仍然是最好的/正确的方式。Goodluck – Nektarios 2011-06-15 16:02:17

回答

2

1)近似但不完全。如果您将应用程序代码划分为三个整体区域:模型,视图和控制器(as documented here),那么Cocoa/XCode环境为您提供了一种“无代码”的方式来处理视图的基本知识:模型的核心数据和控制器的绑定/对象控制器。

撤销管理主要关注模型,而不是视图或控制器。所以它不是真正的Bindings或Object控制器的工作来管理这些东西。看起来你的问题是你使用数组作为你的数据对象,这对于处理这些东西来说太轻了。如果你想撤销支持,你将需要使用核心数据来处理模型,并免费提供这些东西,或者手动推出自己的模型对象(可能包含数组),它们处理这个逻辑。当你完成这些工作后,绑定将间接地让你的生活变得更容易,因为当撤销命令将你的数据恢复到以前的状态时,视图会自动反映这些变化。

此外,NSArrayController的名称有点误导 - 它不是'控制数组'。它确实用于控制与其他数据对象具有多对多关系的数据对象。这让我想起...

2)KVC allows you to treat a to-many relationship作为数组或集合将对象与其他对象之间,无论实际如何实现关系。它通过要求您实施方法fitting a naming convention,其中very closely match the primitive methods of arrays and sets。当您拨打mutableArrayValueForKey:mutableSetValueForKey:时,符合KVC的对象将返回代理阵列或设置,这会将这些方法作为阵列公开。粗略地说,这就是NSArrayController如何知道要调用什么--- KVC在数组的原始对象与其从密钥生成的鬃毛对象之间进行映射。既然你不想使用数组作为你的数据对象,那么能够将任何多对多关系视为仅仅是一个普通的集合,通常是非常有用的。

3)我认为这与你在错误的地方处理撤销有关。执行KVC-compliant methods以在您的数据对象中获取/设置属性,让他们在设置数据的同时更新撤消管理器。您将需要一个特殊的方法让管理员恢复更改,因为您不想将撤销记录为可撤销记录。或者你可以使用核心数据,并免费获得所有这些东西...

+0

感谢您的回答。我刚刚开始阅读关于Core Data的内容! – JPC 2011-06-15 15:20:46