Есть ли у кого-нибудь пример того, как моделировать и кодировать переходное к отношения в CoreData? Например, у меня есть 2 объекта с отношением "один ко многим". Доктор и назначение. Теперь я хочу переходные отношения, называемые mostRecentAppointment на сущности врача. Это легко моделировать в дизайнере xcode, но я не уверен в стороне реализации. Также следует реализовать инверсию? Кажется глупым.
Пример переходных отношений CoreData
Ответ 1
Посмотрите на этот код, который я написал недавно, чтобы кэшировать изображение в объекте NSManagedObject:
Сначала вы определяете свойство переходного процесса в своей модели (обратите внимание, что если ваше свойство переходного процесса указывает на тип объекта, отличный от тех, которые поддерживаются CoreData, вы оставите в качестве "Undefined
" в модели )
Затем вы повторно создаете подкласс NSManagedObject для этого объекта или просто добавьте новое свойство вручную, файл заголовка должен выглядеть следующим образом:
@interface Card : NSManagedObject
@property (nonatomic, retain) NSString * imagePath;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * order;
@property (nonatomic, retain) NSString * displayName;
@property (nonatomic, retain) UIImage *displayImage;
@end
Здесь мы меняем класс свойства переходного процесса на фактический тип класса
например. displayImage
здесь UIImage
.
В файле реализации (или классе расширения) вы реализуете getter/setter для вашего свойства переходного процесса:
-(UIImage*)displayImage{
//Get Value
[self willAccessValueForKey:@"displayImage"];
UIImage *img = (UIImage*)[self primitiveValueForKey:@"displayImage"];
[self didAccessValueForKey:@"displayImage"];
if (img == nil) {
if ([self imagePath]) { //That is a non-transient property on the object
img = [UIImage imageWithContentsOfFile:self.imagePath];
//Set Value
[self setPrimitiveValue:img forKey:@"displayImage"];
}
}
return img;
}
Надеюсь, что это поможет.
Ответ 2
Что вам нужно сделать, это добавить объект типа Назначение newAppointment и установить его каждый раз, когда вы создаете новую встречу для данного врача. Это просто.
Всегда реализуйте обратное, поскольку apple рекомендует это для проверки и эффективности ключевых данных.
В качестве альтернативы вы можете назначить время для встреч и использовать NSPredicates для поиска последней встречи в определенных связанных с Доктором встречах.
Ответ 3
Ну, вам просто нужно попробовать, в вашей собственной примерной программе, которая может быть не более часа, чтобы правильно настроить.
Моя догадка --- никакого дополнительного кодирования не потребуется. Если документация Apple на CoreData правильная, единственное различие между нормальным атрибутом/отношением и "переходным" состоит в том, что последнее не сохраняется, а это означает, что когда вы "сохраняете", он не обновляет постоянное хранилище.
Я бы предположил, что в противном случае все его аспекты будут полными, вместе с соблюдением KVO/KVC, отменой поддержки, проверкой и автоматическим обновлением по правилам удаления. Единственное, что после свежего Fetch объекта --- переходное отношение всегда будет nil.
Для этого --- я бы, конечно, НЕ РЕКОМЕНДУЕТ установить переходные отношения как "не факультативные", потому что для большинства сущностей это скорее всего будет нулевым.
Я бы установил обратную связь (переходный и названный с умом) и оба правила удаления должны быть "Nullify".
До сих пор существует переходное отношение.
Но вот альтернатива, с которой я столкнулся, пытается решить почти ту же проблему. Мое "назначение" - это одно из связанных назначений, но не только "последнее", но и первое "незавершенное". Очень похожая логика.
Вместо переходного отношения я добавил новое вычисляемое свойство в мои подструктуры "Доктор", сгенерированный подкласс NSManagedObject, в категории, например:
@interface XXDoctor (XXExtensions)
/**
@brief Needs manual KVO triggering as it is dependent on a collection.
Alternatively, you can observe insertions and deletions of the appointments, and trigger KVO on this propertyOtherwise it can be auto-
@return the latest of the to-many appointments relation.
**/
@property (readonly) XXAppointment *latestAppointment; // defined as the
@end
Реализация:
#import "XXDoctor".h"
#import "XXAppointment.h"
@implementation XXDoctor (XXExtensions)
// this won't work because "appointments" is a to-many relation.
//+ (NSSet *)keyPathsForValuesAffectingLatestAppointment {
// return [NSSet setWithObjects:@"appointments", nil];
//}
- (XXAppointment *) latestAppointment {
NSInteger latestAppointmentIndex = [self.appointments indexOfObjectPassingTest:^BOOL(XXAppointment *appointment, NSUInteger idx, BOOL *stop) {
*stop = (appointment.dateFinished == nil);
return *stop;
}];
return (latestAppointmentIndex == NSNotFound) ? nil : [self.appointments objectAtIndex: latestAppointmentIndex];
}
@end