树的 KVC 访问器模式

KVC Accessor Patterns for Trees

this document 中,Apple 描述了一对一和对多属性的访问器模式。对多属性涵盖索引和无序集合。

这让我想到了这个问题:
树结构是否有不同的访问器模式,或者我们应该使用(或改编)与其他类型的集合相同的访问器模式?

显然,当持有树结构的 NSArray 绑定到 NSTreeController 时,在我的模型中实现索引对多访问器并在其中设置断点没有任何效果。模型正在正确更新,例如当 adding/removing 个元素,或更改它们的顺序,但从未调用访问器实现时。

我是不是漏掉了什么?

树与数组不同,它不是一种数据结构。您可以从单个根节点开始,在这种情况下 属性 是与该节点的一对一关系,或者从顶级节点数组开始,在这种情况下 属性 是一个到-与这些节点有很多关系。树的其他级别是与那些根节点的独立关系,而不是与提供根节点的对象的关系。

NSTreeController 配置了子键路径。它使用每个节点上的关键路径来访问每个节点的子节点。如果它正在添加或删除节点,那将是通过 KVC 对父节点的子节点进行突变。 (它可能在父对象上使用 -mutableArrayValueForKeyPath:,然后在生成的代理上使用 NSMutableArray 方法。)这应该通过父对象上的索引集合突变访问器。

您确定在正确的 class 上实现了访问器(并在其上设置了断点)吗?

除了使用 KVC 来访问和改变您的 属性,该框架别无选择。如果它们是 属性 命名的,KVC 将使用您的访问器方法。根据您实现 class 的方式,KVC 可能别无选择,只能调用您的访问器方法。例如,您可以实现一个索引集合 属性 而无需任何数组类型 getter 或 setter 或任何数组实例变量来支持它(或者它可以有一个实例变量,其名称是完整的与 属性 名称无关)。

例如,class 可以实现:

- (NSUInteger) countOfEmployess;
- (id) objectInEmployeesAtIndex:(NSUInteger)index;
- (void)insertObject:(id)anObject inEmployeesAtIndex:(NSUInteger)index;
- (void)removeObjectFromEmployeesAtIndex:(NSUInteger)index;

没有任何 -employees-setEmployees: 访问器,也没有任何 employees_employees 实例变量。对于名为 "employees" 的索引集合 属性,它仍然完全符合 KVC。如果给 NSTreeController 这样的节点并配置为使用 "employees" 作为子键路径,它就可以很好地操纵该节点的员工。如果没有那些访问器方法,它还能用什么?

为了更好的衡量,请务必在所有自定义 class 中实施 +accessInstanceVariablesDirectly 至 return NO。这可以捕获拼写错误的 methods/property 名称。