Найти или создать уникальный объект Core Data
Обычный сценарий для приложений, управляемых основными данными, - это получение уникального объекта из хранилища резервных копий. Если объект с определенным уникальным свойством существует, верните его, если он не возвращает вновь созданный объект. Я обнаружил, что повторяю одно и то же много раз, поэтому я завернул его в удобном методе. Но это кажется таким тривиальным, я изобретаю колесо здесь? Есть ли более простой, готовый способ достичь этого?
Cheers,
ЕР
+(id)uniqueEntityfForName:(NSString *)name
withValue:(id)value
forKey:(NSString *)key
inManagedObjectContext:(NSManagedObjectContext *)context {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat:[key stringByAppendingString:@" == %@"], value];
NSArray *result = [context executeFetchRequest:request error:nil];
id entity = [result lastObject];
if (entity == nil) {
entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context];
[entity setValue:value forKey:key];
} else {
entity = [result lastObject];
}
return entity;
}
Я использую этот метод следующим образом:
SomeEntity *entity = [CDUtils uniqueEntityfForName:@"SomeEntity" withValue:@"foo" forKey:@"bar" inManagedObjectContext:context];
Ответы
Ответ 1
Довольно стандартный. Мои основные объекты данных имеют множество методов, таких как [aStudent enrollmentForId:(long long)idValue createIfMissing:YES]
.
Я также хотел бы подключить mogenerator, что устраняет боль от Core Data. Помимо всего прочего, он генерирует метод factory для каждого запроса выборки, определенного в модели данных. Поэтому создание предиката выборки в модели, например,
штук: thingyId == $forThingyId
дает метод сопоставления классов:
+(NSArray *)fetchThingies:(NSManagedObjectContext *)moc forThingyId:(id)thingyId
... который делает первую половину того, что вы там написали. Обертка, подобная
-(Thingy*)thingyForIdValue:(long long)thingyId
является тривиальным для записи, в любом классе содержится ваш managedObjectContext (например, "родительский" объект или делегат приложения или что-то еще.)
Ответ 2
Более гибкое решение - использовать Blocks
, чтобы вызывающий мог обрабатывать 3 ситуации при сравнении двух списков.
- Соответствующие наборы
- Непревзойденные наборы хостов
- Локальные непревзойденные наборы
Поэтому нет необходимости создавать подобные функции при вставке в виде синхронизации или добавления в хранилище данных.
typedef void (^objectOperationBlock)(NSManagedObjectContext *context,
NSDictionary *hostObjectData,
NSManagedObject *localManagedObject);
- (void) insertUniquely:(NSArray *)rawDataArray
entity:(NSString *)entity
matchedBlock:(objectOperationBlock)matchedOperation
hostUnmatchedBlock:(objectOperationBlock)hostUnmatchedOperation
localUnmatchedBlock:(objectOperationBlock)localUnmatchedOperation
error:(NSError **)outError;
Полную реализацию можно найти здесь: http://emplementation.blogspot.com/2011/12/importing-data-into-core-data-while.html