Objective-C撤消经理问题

问题描述

| 我正在阅读有关Objective-c的书,并了解撤消管理器。这个概念看起来很简单,但是提供的示例似乎过于复杂。基本上,我有一个连接到NSArrayController的表视图,并且可以将人添加或删除到数组中,并且可以编辑其名称和内容。由于该示例使用NSArrayController和绑定,因此添加和删除是自动的,所有编辑都是自动的。 根据我的理解,要使用撤消管理器,我需要实现自己的方法来添加/删除/编辑。 由于键值编码,我已经实现了以下方法来执行添加和删除操作并自动调用它们:
- (void)removeObjectFromEmployeesAtIndex:(int)index;
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index;
然后为了进行编辑,我不得不将类注册为观察者,并观察更改以进行编辑:
- (void)changeKeyPath:(NSString *)keyPath
             ofObject:(id)obj
              toValue:(id)newValue
这是我的问题: 我为什么要做那么多?我的理解是,使用NSArrayController和绑定应该使诸如添加/删除/编辑项目之类的事情变得更加容易和自动化。但是,如果无论如何我都必须手动实现所有这些方法以添加撤消支持,为什么还要使用NSArrayController或绑定呢? 幕后发生了什么?在Interface Builder中,添加按钮连接到NSArrayController上的add方法。然后如何调用我的insertObject方法?我知道这是通过键值编码实现的,但是是什么使NSArrayController的add方法仅在我的文档实现此方法的情况下被覆盖? 解决方案是不对称的。我使用一个概念来处理撤消添加/删除操作,而使用另一个概念来处理撤消编辑操作。我也不能只观察阵列的变化吗?我想它将使observeValueForKeyPath方法变得复杂,但这更有意义吗?     

解决方法

        1)差不多,但是不完全一样。如果您将应用程序代码分为三个整体区域:模型,视图和控制器(如此处所述),则Cocoa / XCode环境为您提供了一种“无代码”方式来处理每个基础知识:IB对于视图,对于模型是Core Data,对于控制器是Bindings / Object Controllers。 撤消管理主要是模型的问题,而不是视图或控制器的问题。因此,管理这些东西实际上不是绑定或对象控制器的工作。看来您的问题是您正在使用数组作为数据对象,而数组又太轻巧,无法处理这些东西。如果要撤消支持,则需要使用核心数据来处理模型并免费为您提供这些东西,或者手动滚动处理这种逻辑的自己的模型对象(可能包含数组)。 FWIW,一旦完成此操作,绑定将间接使您的生活变得更轻松,因为当undo命令将数据恢复为之前的状态时,视图将自动反映所做的更改。 另外,NSArrayController的名称有点误导性-它不在“控制数组”中。它确实是用于控制与其他数据对象具有许多关系的数据对象。这带我去... 2)KVC允许您将一个对象与其他对象之间的多对多关系视为数组或集合,而不管该关系是如何实际实现的。为此,需要您实现适合命名约定的方法,这些方法非常匹配数组和集合的原始方法。当您调用
mutableArrayValueForKey:
mutableSetValueForKey:
时,符合KVC的对象将返回一个代理数组或设置一个代理数组,这会将这些方法公开为数组。大致上,这就是NSArrayController知道要调用的方式-KVC在数组的原始对象与一些从键生成鬃毛的方法之间进行映射。由于您不想使用数组作为数据对象,因此将任何多对多关系视为普通集合通常非常有用。 3)我认为这与您在错误的位置处理撤消有关。实现KVC兼容方法以获取/设置数据对象中的属性,让它们在设置数据的同时更新undoManger。您将需要一种特殊的方法来使Undomanager还原更改,因为您不希望撤消记录为可撤消记录。或者,您可以只使用Core Data并免费获得所有这些东西...     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...