objective-c - 绑定(bind)到 Core Data 中的关系属性

标签 objective-c cocoa core-data cocoa-bindings

我是核心数据新手,我遇到了一个问题,我无法理解如何以“正确的方式”进行操作

我会尝试举例说明我的问题。

我有一辆实体汽车。以及我的程序中所有汽车的列表。汽车有一些属性,但它们不是预定义的。因此,对于每辆车,我希望能够定义一些属性。 因此,我定义了一个新的实体 CarProperty,与汽车具有一对多的关系。

在 nscollectionview 中,我想显示汽车的一些属性,更具体的是它行驶的公里数 (numKm)(如果该属性存在)。所以我想将它绑定(bind)到标签上。但怎么办呢?

我不能说representedObject.properties.numKm,或representedObject.numKm

我应该如何解决这个问题?

希望这是有道理的。

最佳答案

这不是一个简单的问题。问题是,Core Data 对 numKm 作为属性一无所知。它如何知道 numKm 对应于特定的 CarProperty 对象?

您描述的根本问题是键值编码合规性。 Cocoa 将在 properties 对象上查找名为 numKm 的方法。如果找不到,它将尝试发送 [properties valueForKey:@"numKm"]; 因为 valueForKey: 不知道如何处理 numKm 时,您会收到错误,但在调用 [properties valueForUndefinedKey:@"numKm"]

之前发生

但这里有一个问题:properties 是由 Core Data 生成的 NSSet,因此您无法对其进行子类化以覆盖 valueForUndefinedKey:。您可以做的是为您的任意属性创建符合 KVC 的自己的对象并使用它。

一种解决方案是子类化 NSDictionary 并使其充当代理。原始方法是 countobjectForKey:keyEnumerator。如果您重写这三个方法,则可以创建一个链接到您的 Car 对象的 NSDictionary 并返回相应的 CarProperty 对象。例如:

@interface PropertyProxy : NSDictionary {
}
@property (nonatomic, readonly, assign) Car *car;

- (id)initWithCar:(Car *)car

@end

@implementation PropertyProxy

@synthesize car = _car;

- (id)initWithCar:(Car *)car {
    if (!(self = [super init]))
        return nil;

    _car = car;

    return self;
}

- (NSInteger)count {
    return [car.properties count];
}

- (id)objectForKey:(NSString *)key {
    return [[car.properties filteredSetUsingPredicate:[NSPredicate predicateWithFormt:@"key == %@", key]] anyObject];
}

- (NSEnumerator *)keyEnumerator {
    return [[car valueForKeyPath:@"properties.key"] objectEnumerator];
}

@end

然后,在您的 Car 类中执行以下操作:

@interface Car : NSManagedObject {
    // other stuff
}

@property (nonatomic, readonly) NSDictionary *carProperties;

// other stuff

@end

@implementation Car

// other stuff

- (NSDictionary *)carProperties {
    return [[[PropertyProxy alloc] initWithCar:self] autorelease];
}

@end

(免责声明:我只是将其输入到我的网络浏览器中,因此不能保证它实际上可以编译:-))

正如您所见,这并不是世界上最容易做的事情。您将能够像这样设置关键路径:

representedObject.carProperties.numKm;

请记住,虽然这是符合键值编码的,但它不符合键值观察的。因此,如果 numKm 发生变化,您将无法观察到这一点。您需要做一些额外的工作才能实现这一点。

关于objective-c - 绑定(bind)到 Core Data 中的关系属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3024767/

相关文章:

iphone - CoreData中的 transient 属性

ios - 属性越少,核心数据性能是否越好?

iphone - 需要/想要将 NSError** 作为参数传递给 performSelector

ios - 如何使按钮的角变圆

objective-c - Objective-C 中的 Swift 字典作为 NSMutableDictionary

xcode - 如何诊断拖动过程中的意外延迟?

iphone - iOS 6 的界面方向不起作用

macos - 弹出框未连接到 anchor

objective-c - 委托(delegate)/选择器和目标/操作之间有区别吗?

iOS swift : Store cache using coredata (cloudkit)