核心数据:如何在不通过字符串引用实体的情况下创建托管对象

Posted

技术标签:

【中文标题】核心数据:如何在不通过字符串引用实体的情况下创建托管对象【英文标题】:Core Data: How to create a Managed Object without referencing the entity by string 【发布时间】:2013-01-06 04:39:14 【问题描述】:

为了提高代码的可读性,我一直在为我的实体生成 Core Data 类,这样我就可以使用 getter 和 setter(我个人使用点符号)而不是 setValue: forKey:

来访问它们

例如,代替[aDateObject setValue:nameString forKey:@"name"]; 我将使用:aDateObject.name = nameString; 我想知道是否有一种等效的方法可以将新的托管对象插入到托管对象上下文中。例如,我目前使用以下内容创建一个新的DateTimeFlightDataType

    aDateObject = (DateTimeFlightDataType*)[NSEntityDescription insertNewObjectForEntityForName:@"DateTimeFlightDataType"
                                                                         inManagedObjectContext:self.managedObjectContext];

有没有办法使用我的类 (DateTimeFlightDataType) 而不是实体字符串名称来创建此对象并将其插入到上下文中以保持一致性?

【问题讨论】:

我认为一个好的方法是“开始使用 Mogenerator” :) 它会为您提供避免使用字符串常量的类和方法。 很公平,我看到很多关于使用 Mogenerator 的讨论(包括一些避免它的建议)。它可能比我真正需要的更重,并且最终添加了另一个依赖项,如果不需要,我宁愿避免,这就是为什么我正在寻找是否有本地方法来做到这一点。 NSManagedObject 上使用 NSStringFromClass 的类别可以工作 - 我不在我的 mac ATM 上,所以不想在手机上输入示例代码... 请参阅 ***.com/questions/14049592/… 以了解使用 NSStringFromClass 和替代解决方案的示例。 【参考方案1】:

你可以写:

NSString *name = NSStringFromClass([DateTimeFlightDataType class]);
NSManagedObjectContext *ctx = self.managedObjectContext;
aDateObject = [NSEntityDescription insertNewObjectForEntityForName:name 
                                            inManagedObjectContext:ctx];

【讨论】:

谢谢。有道理——同样的方法调用,我们只是从类中获取字符串名称。它也将实体名称与类分离(如果这很重要的话)。最后,它实际上使代码更难遵循,至少对我来说(我是 ios 编程的新手),但如果你试图避免直接引用实体。 这样做的好处是您可以避免拼写错误,重构也变得更容易。 我必须同意这一点。我正在教一个朋友使用 Core Data(以及模式),并试图让事情尽可能简单“看起来”。但我认为从解耦、重构的角度来看,这将是我的首选方法。 我喜欢这种方法,但如果你的类和实体有不同的名称,它显然行不通。 +1 因为这是动态插入新实体的好方法。但是,在正常情况下,这(在我看来)比仅仅传递一个带有实体名称的字符串可读性差......【参考方案2】:

创建 MO 总是需要一个实体,并且这些实体总是由一个字符串定义的。

常见的方法是通过某种方式使字符串不需要硬编码,但可以从 MO 的类派生出来。通常使用NSStringFromClass

【讨论】:

我没有足够的代表来投票,否则我会将其标记为有用!

以上是关于核心数据:如何在不通过字符串引用实体的情况下创建托管对象的主要内容,如果未能解决你的问题,请参考以下文章

在不获取现有对象的情况下创建核心数据关系

如何在不违反主键约束的情况下插入具有循环引用的实体框架

如何让实体框架在不保存对象的情况下创建/更新数据库表

带有 NSNumber 的 NSArray 的 NSPredicate(核心数据)

如何在不清除数据库的情况下重新加载 Roo 项目?

我可以在不创建实体类的情况下对大型 sql 使用休眠命名查询吗?