【问题标题】:NSOutlineView and Object Persistence Odd BehaviorNSOutlineView 和对象持久性奇怪的行为
【发布时间】:2014-03-17 13:24:53
【问题描述】:

我很难接受这个。当谈到基于视图的 NSOutlineView 的对象持久性时,我遇到了一个非常奇怪的行为。目前我有一个对象,其中包含一个object1数组,该数组包含一个object2数组,该数组包含一个object3数组,等等......每个类(对象)都有一个isEqual:方法和一个isEqualToObject:方法。我一遍又一遍地修改了这些,它们工作得很好。

现在当我展开一个项目时,它被保存到默认 plist 并且我已经检查过,保存的项目数是正确的。

但是当我再次打开我的文档时会发生什么;有时所有行都完全按照我离开时的方式展开,有时没有任何行展开,有时 NSOutlineView 会展开一些行,但不会展开其他行。

请注意,我没有使用 NSTreeController。我正在使用 NSOutlineView 数据源和委托。以下方法是这样实现的。还设置了大纲视图的 AutoSave 名称。

- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item {
        return [NSKeyedArchiver archivedDataWithRootObject:item];
    }

- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object {
        return [NSKeyedUnarchiver unarchiveObjectWithData:object];

}

基本上有时它会起作用,有时它会起作用,有时根本不起作用。这是非常随机的。

奇怪的是,我放置了 NSLog 并且每个项目都在寻找匹配项,但是......大纲视图没有扩展它。

【问题讨论】:

  • 我认为您应该使用[item representedObject] 来获取底层对象,也就是您的模型中的对象。
  • 此外,在检查我的代码时,我发现我调用了我的文档类 [self.groupView setAutosaveExpandedItems:YES];awakeFromNib。我记得读过你必须手动调用它。我假设您还设置了自动保存名称?
  • 我已经设置了自动保存名称。 [项目代表对象] 仅在我使用未使用的 NSTreeController 时才有效。

标签: cocoa nsoutlineview


【解决方案1】:

我让它工作了。所以我最终做的是在我拥有的每个数组中搜索对象并返回匹配的对象(不是persistentObject,而是已经成为我数据一部分的对象)。换句话说

- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object {

    id persistentObject =[NSKeyedUnarchiver unarchiveObjectWithData:object];

    for (Class * a in dataArray) {
        if ([a isEqual:persistentObject]) {
            return a;  //instead of returning persistentObject
        }
    }
}

这成功了。我为此进行了长期广泛的搜索,希望有人觉得它有用。

【讨论】:

  • 您能再解释一下您的设置吗?我遇到了麻烦,听起来您的模型与我的模型相似,但我不确定。基本上,我有一组“组”对象(也就是使用HeaderCell 标识符作为其视图的项目)。在每个组中,我都有可以嵌套或不嵌套的项目。基本上,这个:
  • groups = @[itemArray, itemArray, itemArray]; 在那些项目数组中,有“项目”,有些还有孩子;有些没有。我对您的 for 循环有点困惑。你到底在保存什么?附言我所有的数据模型对象都符合 NSCoding 标准。
  • @BenStock 我没有保存任何东西。我正在返回数组中的对象。您的示例应类似于 - (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item { return [NSKeyedArchiver archivedDataWithRootObject:item]; } - (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object { id item = [NSKeyedUnarchiver unarchiveObjectWithData:object]; for (NSArray * array in groups) { for (id testItem in array) { if ([item isEqual:testItem]) { return testItem; } } } }
  • 好的,我明白你在说什么。为什么不能只返回未归档的对象?我在其他地方读到,在自定义模型对象中,必须实现 -isEqual: 方法,从您所写的内容来看,情况似乎如此。附言很抱歉问你在保存什么。我的意思是问:你到底在归档/取消归档什么?整个对象、标识符、索引集等,但我现在可以看到它是项目。凉爽的。感谢您的帮助。
  • 因为计算机是根据内存来思考的。您已分配的对象与您取消归档的对象占用不同的内存空间。因此,您必须在每个对象中实现 isEqual 并进行匹配。另一种方法是为每个对象创建一个 UUID,将其存档,然后取消存档,在您的对象中搜索匹配的 UUID 并返回该对象。你在正确的轨道上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 2019-03-21
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
相关资源
最近更新 更多