我遇到了一个问题,其中一些简单的 Cocoa 绑定正在更改附加到具有自动重新排列内容集的 ArrayController 的提取谓词。
我的数据模型有三个类(我们称它们为 A、B 和 C)。它以严格的层次结构排列,其中一个class_A的实例拥有一个或多个class_B的实例,每个实例拥有一个或多个class_C的实例;并且类 B 和 C 的每个实例都有对其父级的弱引用。例如:
@interface Class_A
@property (strong) NSArray *collection_of_b;
@property BOOL foo;
@end
@interface Class_B
@property (weak) Class_A class_A;
@property (strong) NSArray *collection_of_c;
@property (weak) SomeOtherClass bar;
@end
@interface Class_C
@property (weak) Class_B class_B;
@property (weak) SomeOtherClass baz;
@end
我在一个大的主从视图中显示了这个层次结构。有一个包含所有 class_A 实例列表的第一个表视图;选择后,第二个表格视图会显示 class_B 实例的列表;再次选择后,第三个表格视图会显示 class_C 实例的列表。
在每个列表下方,有一组字段绑定到所选的 class_A、class_B 或 class_C 实例的各种属性(如 foo、bar 和 baz)。这些字段要么使用严格符合 KVO 的访问器来修改类成员,要么我只是将字段直接绑定到选择成员。(例如,class_A.foo 绑定到一组表示“是”和“否”的单选按钮。)所有这些似乎都运行良好。
现在,这是踢球者。在同一个窗口的另一部分,我展示了一个具有一些属性的 class_C 实例的过滤列表。为了呈现过滤后的列表,我使用了一个过滤谓词来指定一些标准,例如“(class_B.bar == some value) OR (class_B.class_A.foo == YES)”。过滤工作完美......直到我通过绑定字段更改 foo 或 bar 的值,当我的应用程序立即崩溃并显示以下消息:
“无法从 <Class_B instance> 中删除键路径“bar”的观察者,很可能是因为键“bar”的值已更改而未发送适当的 KVO 通知。请检查 Class_B 类的 KVO 合规性。”
我已将问题缩小到 ArrayController 的自动重新排列内容设置。当我关闭它时,当实例的过滤属性发生变化时,表格不会自动调整内容,但它也不会崩溃。当然,我可以手动触发重新排列,但这是一个不雅的解决方案。
一些搜索显示 2009 年 cocoa-dev 线程报告了与自动排列内容完全相同的行为作为错误:
https://groups.google.com/forum/?hl=en&fromgroups#!topic/cocoa-dev/SpXF0__B4dE
不过,不确定可以做些什么。有什么想法吗?