I'm encountering a problem where some simple Cocoa bindings are altering a fetch predicate attached to an ArrayController that has Auto Rearrange Content set.
My data model has three classes (we'll call them A, B, and C). It's arranged in a strict hierarchy, where an instance of class_A owns one or more instances of class_B, each of which owns one or more instances of class_C; and each instance of classes B and C has a weak reference to its parent. For example:
@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
I'm showing this hierarchy in a large master-detail view. There's a first table view with a list of all class_A instances; upon selection, a second table view presents the list of class_B instances; and upon selection again, a third table view presents the list of class_C instances.
Beneath each list, there's a set of fields bound to various properties of the selected instance of class_A, class_B, or class_C (like foo, bar, and baz). These fields either use strictly KVO-compliant accessors to modify the class members, or I'm just binding the field straight to the selection member. (For example, class_A.foo is bound to a set of radio buttons for YES and NO.) All of that seems to be working perfectly.
Now, here's the kicker. In another part of the same window, I'm presenting a filtered list of class_C instances having some properties. To present that filtered list, I'm using a filter predicate specifying some criteria like "(class_B.bar == some value) OR (class_B.class_A.foo == YES)". The filtering works perfectly... until I alter the values of foo or bar through the bound fields, when my app instantly crashes with the following message:
"Cannot remove an observer for the key path "bar" from <Class_B instance>, most likely because the value for the key "bar" has changed without an appropriate KVO notification being sent. Check the KVO-compliance of the Class_B class."
I've narrowed the problem down to the Auto Rearrange Content setting of the ArrayController. When I turn this off, the table doesn't automatically adjust the content when the filtered properties of the instances change, but it also doesn't crash. Of course, I can manually trigger the rearranging, but it's an inelegant solution.
Some searching revealed a 2009 cocoa-dev thread reporting the exact same behavior of Auto Arrange Content as a bug:
https://groups.google.com/forum/?hl=en&fromgroups#!topic/cocoa-dev/SpXF0__B4dE
Not sure what can be done about it, though. Any thoughts?