objective-c - 使用 KVO 更新由 NSPredicate 过滤的 NSTableView

标签 objective-c cocoa key-value-observing key-value-coding

我的 UI 没有按预期更新。

该应用程序使用类似于 iTunes 的 View 显示“项目”——左侧的源列表可让您过滤右侧的列表 (NSTableView)。当我的过滤器检查任何简单字段(如名称、字符串)时,它们会正确更新,但不适用于数组(如标签)。

我正在从我的一个对象(来自名为“tags”的 NSMutableArray 字段)中删除一个标签,并且我希望它从列表中消失,因为它不再与绑定(bind)到我的表的 NSArrayController 的谓词匹配。

ProjectBrowser.mm:

self.filter = [NSPredicate predicateWithFormat:@"%@ IN %K", 
                                               selectedTag, 
                                               @"tags"];

项目.mm:

[self willChangeValueForKey:@"tags"];
[tags removeAllObjects];
[self didChangeValueForKey:@"tags"];

我也试过了,但结果是一样的:

[[self mutableArrayValueForKey:@"tags"] removeAllObjects];

界面生成器设置:

  • ProjectBrowser 对象是 XIB 的文件所有者
  • NSArrayController(项目 Controller )的内容数组绑定(bind)到“文件所有者”.projects
  • 项目 Controller 的过滤谓词绑定(bind)到“File's Owner”.filter
  • NSTableView 的列绑定(bind)到“Project Controller”.name

最佳答案

我在文档中找到了这个(KVC Compliance - Dependent Values):

Important: Note that you cannot set up dependencies on to-many relationships. For example, suppose you have an Order object with a to-many relationship (orderItems) to a collection of OrderItem objects, and OrderItem objects have a price attribute. You might want the Order object have a totalPrice attribute that is dependent upon the prices of all the OrderItem objects in the relationship. You can not do this by implementing keyPathsForValuesAffectingValueForKey: and returning orderItems.price as the keypath for totalPrice. You must observe the price attribute of each of the OrderItem objects in the orderItems collection and respond to changes in their values by updating totalPrice yourself.

因此,当 key 路径中存在一对多关系时,您不能依赖 KVO 依赖项或通知。这适用于我的标签数组,因此我添加了一些代码来修补这个损坏的链接。

当我将项目添加到“projects”数组时:

[newProject addObserver:self forKeyPath:@"tags" options:NSKeyValueObservingOptionNew context:nil];  

重要的部分:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([object isKindOfClass:[CProject class]] && [keyPath isEqualToString:@"tags"])
    {
        [self willChangeValueForKey:@"projects"];
        [self didChangeValueForKey:@"projects"];
    }
}

当我删除项目时进行清理:

[project removeObserver:self forKeyPath:@"tags"];

不确定这是否是最佳解决方案,但它使我的列表保持更新。

关于objective-c - 使用 KVO 更新由 NSPredicate 过滤的 NSTableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2870792/

相关文章:

ios - 如何引用和声明 UINavigationController 的自定义方法

objective-c - lldb 跳过 objc_msgSend

objective-c - 在 macOS 应用程序中,我有一个后台线程执行一行代码,需要花费大量时间。如何取消封禁?

objective-c - KVC一致性测试

objective-c - 在模型更改时自动更新 NSOutlineView,无需 NSTreeController

ios - 应用程序发送到后台后位置停止更新

cocoa - 尝试获取 textView macOS 的插入点

objective-c - 在方法中,指针或实际对象是否作为参数传递?

ios - 如何在应用 UIKit Dynamics 重力的同时获取 UIView 的框架更新?

iOS, KVO : Observer fails to track change to myObject. myCALayer.center