gpt4 book ai didi

cocoa - NSOutlineView、NSTreeController 和异构层次结构

转载 作者:行者123 更新时间:2023-12-03 17:07:50 26 4
gpt4 key购买 nike

在 Marcus Zarra 的《核心数据》一书中的第 40 页中,他建议,由于 NSTreeController 需要相同的 key 来访问层次结构中的所有对象(例如子对象),并且这可能意味着意义不大的关系名称,因此您可以编写额外的内容所需关系的访问器。我认为这是一个好主意,但我不确定如何实现。

让我以 Aperture 的数据模型为例:你可以有很多库,每个库可以有很多项目,每个库可以有很多照片。因此,如果我将我的实体命名为项目照片及其关系项目照片 和什么都没有,以下是库的正确实现吗?

库.h

@interface Library: NSManagedObject {
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSSet *projects;
@property (nonatomic, retain) NSSet *children;
@property (nonatomic, retain) id parent;
@end

@interface Library (CoreDataGeneratedAccessors)
- (void)addProjectsObject:(Project *)value;
- (void)removeProjectsObject:(Project *)value;
- (void)addProjects:(NSSet *)value;
- (void)removeProjects:(NSSet *)value;
- (id)parent;
- (void)setParent;
@end

和Library.m

#include "Library.h" 

@implementation Library

@dynamic title;
@dynamic projects;

- (NSSet*) children {
[self willAccessValueForKey:@"children"];
NSSet *set = [self valueForKey:@"projects"];
[self didAccessValueForKey:@"children"];
return set;
}

- (void) setChildren:(NSSet*)children {
[self willChangeValueForKey:@"children"];
[self setValue:children forKey:@"projects"];
[self didChangeValueForKey:@"children"];
}

- (id)parent {
[self willAccessValueForKey:@"parent"];
[self didAccessValueForKey:@"parent"];
return nil;
}

- (void)setParent:(id)parent {
// Proposed parent value is ignored. Libraries have no parent.
[self willChangeValueForKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}

@end
  1. 子项和父项应该是头文件中的属性吗?

  2. 这是建议的实现吗?我还应该包含 addChildrenObject:removeChildrenObject:addChildren:removeChildren: 吗?并实现它们? (父方法也是如此。)

  3. 我假设子项根本不会出现在核心数据模型中。是对的吗?那么反向关系是如何推断的呢?

  4. 我应该在 setChildren 中调用 [self willChangeValueForKey:@"children"] 吗:这样 Children 就符合 KVO 要求了吗? (其他访问器也是如此。)

  5. 在第 41 页中,M. Zarra 建议实现 NSOutlineDataSource 而不是使用 NSTreeController,因为“结果可能是意外且不清楚的”。有谁知道这些限制是什么?

  6. 最后,如果我实现 NSOutlineDataSource,您会建议缓 stub 对象的获取吗?如果是这样,保持此缓存数组与核心数据同步的正确方法是什么?

谢谢。

最诚挚的问候,

豪尔赫

最佳答案

我在这里看到的问题是,虽然设置“children”属性将触发“projects”属性的 KVO,但反之则不然。因此,如果您通过“projects”关系将项目添加到库对象,大纲 View 将不会更新,因为它不会看到“children”属性中的任何更改。

启用此功能的最简单方法是实现如下方法:

+ (NSSet*)keyPathsForValuesAffectingChildren
{
return [NSSet setWithObject:@"projects"];
}

这应该会使“projects”属性的任何更改也会触发“children”的 KVO 通知。

顺便说一句,由于“children”属性不是核心数据模型的一部分,我认为 will/didAccessValueForKey: 调用不是绝对必要的,尽管我不认为我认为他们不会伤害任何东西。另外,如果你实现了我上面提到的方法,你应该不再需要在 setChildren: 方法中调用 will/didChangeValueForKey: ,因为 Cocoa 应该自动触发 KVO当“projects”键改变时。

关于cocoa - NSOutlineView、NSTreeController 和异构层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3079839/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com