Это не простая проблема.Дело в том, что Core Data ничего не знает о numKm
как о свойстве.Как узнать, что numKm
соответствует определенному CarProperty
объекту?
Фундаментальная проблема, которую вы описываете, - это соответствие кодирования ключ-значение.Какао будет искать метод с именем numKm
для объекта properties
.Не найдя его, он попытается отправить [properties valueForKey:@"numKm"];
Поскольку valueForKey:
не знает, что делать с numKm
, вы получите сообщение об ошибке, но не раньше, чем он вызовет [properties valueForUndefinedKey:@"numKm"]
Но вотcatch: properties
- это NSSet
, сгенерированный Core Data, поэтому вы не можете создать подкласс для переопределения valueForUndefinedKey:
.Что вы можете сделать, так это создать собственный объект, совместимый с KVC для ваших произвольных свойств, и использовать его вместо этого.
Одним из решений является создание подкласса NSDictionary
и его использование в качестве прокси.Примитивные методы: count
, objectForKey:
и keyEnumerator
.Если вы переопределите эти три метода, вы можете создать NSDictionary
, который связан с вашим Car
объектом и возвращает соответствующие 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
(Отказ от ответственности: я только что набрал это в своем веб-браузере, так что на самом деле нет никаких гарантийcompiles: -))
Как видите, это не самая легкая вещь в мире.Вы сможете настроить ключевые пути следующим образом:
representedObject.carProperties.numKm;
Имейте в виду, что, хотя это значение ключа кодирование , оно не является значением ключа соблюдая соответствует.Поэтому, если numKm
изменится, вы не сможете это заметить.Чтобы это произошло, вам нужно проделать дополнительную работу.