Привязка к свойству отношений в Core Data - PullRequest
0 голосов
/ 11 июня 2010

Я новичок в базовых данных, и у меня возникла проблема, я не могу понять, как сделать "правильный путь"

Я попытаюсь привести пример моей проблемы.

У меня есть автомобиль.И список всех автомобилей в моей программе.У автомобилей есть некоторые атрибуты, но они не определены заранее.Поэтому для каждой машины я хочу определить некоторые свойства.Поэтому я определил новую сущность CarProperty, имеющую отношение один-ко-многим с автомобилем.

В обзоре nscollection я хотел бы показать некоторые свойства автомобиля, более конкретно, количество пройденных километров (numKm) (если это свойство существует).Поэтому я хочу связать это с лейблом.Но как это сделать?

Я не могу сказать representedObject.properties.numKm или representedObject.numKm.

Как мне обойти это?

Надеюсь, это имеет смысл.

1 Ответ

1 голос
/ 11 июня 2010

Это не простая проблема.Дело в том, что 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 изменится, вы не сможете это заметить.Чтобы это произошло, вам нужно проделать дополнительную работу.

...