1

我的 UI 没有在我期望的时候更新。

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

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

项目浏览器.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(项目控制器)的内容数组绑定到“文件所有者”.projects
  • 项目控制器的过滤谓词绑定到“文件的所有者”.filter
  • NSTableView 的列绑定到“项目控制器”.name
4

2 回答 2

2

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

重要提示:请注意,您不能设置对多关系的依赖关系。例如,假设您有一个 Order 对象,它与 OrderItem 对象的集合具有一对多关系 (orderItems),并且 OrderItem 对象具有 price 属性。您可能希望 Order 对象有一个 totalPrice 属性,该属性取决于关系中所有 OrderItem 对象的价格。您不能通过实现 keyPathsForValuesAffectingValueForKey: 并返回 orderItems.price 作为 totalPrice 的 keypath 来做到这一点。您必须观察 orderItems 集合中每个 OrderItem 对象的价格属性,并通过自己更新 totalPrice 来响应其值的变化。

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

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

[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"];

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

于 2010-05-21T23:09:48.780 回答
0

我很惊讶您的第一个代码片段甚至可以编译。它也可能无法像您期望的那样工作,因为

self.property = foo;

是语法糖

[自我设置属性:foo];

无论如何,您的问题可能是您没有观察到tags。我不确定谓词是否会自动观察其查询字符串中的键。

于 2010-05-20T08:54:50.443 回答