objective-c – 核心数据查找或创建最有效的方式
我有大约10000个实体“消息”的对象.当我添加一个新的“消息”时,我想先看看它是否存在 – 如果它只是更新它的数据,但是如果不创建它.
现在,“find-or-create”算法通过将所有Message对象的objectID保存在一个数组中,然后过滤并使用existingObjectWithID获取消息:error: 这样可以正常工作,但是在我使用existingObjectWithID获取“消息”的情况下,然后尝试通过设置“消息”对象的属性并调用保存来设置和保存属性:在上下文中,它不正确保存.有人遇到这样的问题吗? 有没有更有效的方法来创建或创建算法? 解决方法
首先,消息是CoreData实体的“坏”名称,因为苹果内部使用它,并在后续的开发中引起问题.
你可以阅读更多关于它 HERE 我注意到所有建议的解决方案都使用数组或提取请求. 在单个线程/上下文应用程序中,通过将新插入的对象(类型为Message)添加到高速缓存(字典)中,并使用现有的对象标识和键映射预先填充高速缓存,可以实现这一任务. 考虑这个界面: @interface UniquenessEnforcer : NSObject @property (readonly,nonatomic,strong) NSPersistentStoreCoordinator* coordinator; @property (readonly,strong) NSEntityDescription* entity; @property (readonly,strong) NSString* keyProperty; @property (nonatomic,readonly,strong) NSError* error; - (instancetype) initWithEntity:(NSEntityDescription *)entity keyProperty:(NSString*)keyProperty coordinator:(NSPersistentStoreCoordinator*)coordinator; - (NSArray*) existingObjectIDsForKeys:(NSArray*)keys; - (void) unregisterKeys:(NSArray*)keys; - (void) registerObjects:(NSArray*)objects;//objects must have permanent objectIDs - (NSArray*) findOrCreate:(NSArray*)keys context:(NSManagedObjectContext*)context error:(NSError* __autoreleasing*)error; @end 流: 1)在应用程序启动时,分配一个“唯一执行者”并填充缓存: //private method of uniqueness enforcer - (void) populateCache { NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init]; context.persistentStoreCoordinator = self.coordinator; NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:self.entity.name]; [r setResultType:NSDictionaryResultType]; NSExpressionDescription* objectIdDesc = [NSExpressionDescription new]; objectIdDesc.name = @"objectID"; objectIdDesc.expression = [NSExpression expressionForEvaluatedObject]; objectIdDesc.expressionResultType = NSObjectIDAttributeType; r.propertiesToFetch = @[self.keyProperty,objectIdDesc]; NSError* error = nil; NSArray* results = [context executeFetchRequest:r error:&error]; self.error = error; if (results) { for (NSDictionary* dict in results) { _cache[dict[self.keyProperty]] = dict[@"objectID"]; } } else { _cache = nil; } } 2)当你需要测试存在时,只需使用: - (NSArray*) existingObjectIDsForKeys:(NSArray *)keys { return [_cache objectsForKeys:keys notFoundMarker:[NSNull null]]; } 3)当你喜欢实际获取对象并创建缺失的对象时: - (NSArray*) findOrCreate:(NSArray*)keys context:(NSManagedObjectContext*)context error:(NSError* __autoreleasing*)error { NSMutableArray* fullList = [[NSMutableArray alloc] initWithCapacity:[keys count]]; NSMutableArray* needFetch = [[NSMutableArray alloc] initWithCapacity:[keys count]]; NSManagedObject* object = nil; for (id<NSCopying> key in keys) { NSManagedObjectID* oID = _cache[key]; if (oID) { object = [context objectWithID:oID]; if ([object isFault]) { [needFetch addObject:oID]; } } else { object = [NSEntityDescription insertNewObjectForEntityForName:self.entity.name inManagedObjectContext:context]; [object setValue:key forKey:self.keyProperty]; } [fullList addObject:object]; } if ([needFetch count]) { NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:self.entity.name]; r.predicate = [NSPredicate predicateWithFormat:@"SELF IN %@",needFetch]; if([context executeFetchRequest:r error:error] == nil) {//load the missing faults from store fullList = nil; } } return fullList; } 在这个实现中,您需要自己跟踪对象的删除/创建. 多线程的情况要复杂得多(相同的接口,但是在考虑性能的时候,完全不同). 一些数学: 鉴于: 这可能是一个很高的估计,但你应该考虑到这一点… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |