【问题标题】:Find or create unique Core Data entity查找或创建唯一的核心数据实体
【发布时间】:2011-06-25 20:12:36
【问题描述】:

核心数据驱动应用程序的一个常见场景是从后备存储中获取唯一对象。如果具有某个唯一属性的对象存在,则返回该对象,如果它不返回新创建的对象。我发现自己一遍又一遍地写同样的东西,所以我用一种方便的方法把它包装起来。但这似乎微不足道,我在这里重新发明轮子吗?有没有更简单、开箱即用的方法来实现这一目标?

干杯,
EP

+(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];

【问题讨论】:

  • 看起来有效。用于非 GC 项目时可能存在内存泄漏,因为您没有释放 request
  • 完全!我仍然需要与内存释放保持一致。更新代码。
  • 相当标准。我的核心数据实体有很多方法,例如 [aStudent registrationForId:(long long)idValue createIfMissing:YES]。我还想插入 mogenerator rentzsch.github.com/mogenerator ,这消除了 Core Data 的许多痛苦。除其他外,它为数据模型中定义的每个获取请求生成一个工厂方法。因此,制作一个 fetch 谓词,例如,thingies:“thingyId == $forThingyId”会产生一个匹配的类方法:+(NSArray *)fetchThingies:(managedObjectContext *)moc forThingyId:(id)thingyId,它完成了前半部分的工作你已经在上面写了。
  • (澄清一下:mogenerator 不是我的。我刚刚有过很好的经验。)
  • 如果你愿意,@rgeorge,你能把它放在答案中,这样我就可以将它标记为已回答?否则我最终会自己添加答案,谢谢。那台发电机是一个很棒的补充。

标签: objective-c core-data unique insert-update


【解决方案1】:

相当标准。我的核心数据实体有很多方法,比如[aStudent enrollmentForId:(long long)idValue createIfMissing:YES]

我还想插入 mogenerator ,它消除了 Core Data 的许多痛苦。除其他外,它为数据模型中定义的每个获取请求生成一个工厂方法。因此,在模型中创建一个 fetch 谓词,例如,

东西: thingyId == $forThingyId

产生一个匹配的类方法:

+(NSArray *)fetchThingies:(NSManagedObjectContext *)moc forThingyId:(id)thingyId

...它完成了您在那里所写内容的前半部分。像

这样的包装器
-(Thingy*)thingyForIdValue:(long long)thingyId

然后在任何包含 managedObjectContext 的类中(例如,“父”实体、应用程序委托或其他任何类)都可以轻松编写。

【讨论】:

  • mogenerator + 保存的获取请求 == 好主意。谢谢!
【解决方案2】:

更灵活的解决方案是使用Blocks让调用者在比较两个列表时处理3种情况。

  1. 匹配集
  2. 主机不匹配集
  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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多