【问题标题】:Cocoa bindings + filter predicate + Auto Rearrange Content = crashCocoa 绑定 + 过滤谓词 + 自动重新排列内容 = 崩溃
【发布时间】:2012-08-15 00:14:03
【问题描述】:

我遇到了一个问题,一些简单的 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 的值,当我的应用程序立即崩溃并显示以下消息:

“无法从 中删除键路径“bar”的观察者,很可能是因为键“bar”的值已更改而未发送适当的 KVO 通知。检查 Class_B 的 KVO 合规性类。”

我已将问题缩小到 ArrayController 的自动重新排列内容设置。当我关闭它时,当实例的过滤属性发生变化时,表格不会自动调整内容,但它也不会崩溃。当然,我可以手动触发重新排列,但这是一个不雅的解决方案。

一些搜索发现 2009 年 cocoa-dev 线程报告了与自动排列内容完全相同的行为作为错误:

https://groups.google.com/forum/?hl=en&fromgroups#!topic/cocoa-dev/SpXF0__B4dE

但不确定可以采取什么措施。有什么想法吗?

【问题讨论】:

    标签: xcode cocoa nspredicate cocoa-bindings key-value-observing


    【解决方案1】:

    我猜你的问题的根源在这里:

    @property (weak) SomeOtherClass bar;
    
    @property (weak) Class_B class_B;
    

    当这些对象被释放时,它们的实例变量被运行时设置为 nil,但不会发出 KVO 通知。

    尝试将这些更改为 strong 属性,看看是否能解决问题。

    有一些good, but complex explanation about this situation in this blog post

    【讨论】:

    • 谢谢 - 这是一个有趣的评估。我不愿意使用强引用来解决这个问题,因为它打破了强与弱的整体观点:建立一个严格的、分层的所有权顺序,避免了保留周期。我会考虑你的想法,看看我能不能找到一个中间解决方案。
    • 通过暂时将它们切换为强,您可以明确确定是哪一个导致了问题。此时,您可以决定使用自动重新排列过滤谓词还是使用弱引用更重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多