如何在 Core Data 模型中动态创建新实体(表)?
Posted
技术标签:
【中文标题】如何在 Core Data 模型中动态创建新实体(表)?【英文标题】:How to dyanmic create a new entity (table) via CoreData model? 【发布时间】:2011-03-17 16:08:04 【问题描述】:我想在 SQLite 中创建一个新的实体(表)。我的代码如下:
+(BOOL)CreateDataSet:(NSManagedObjectModel *) model
attributes:(NSDictionary*)attributes
entityName:(NSString*) entityName
NSEntityDescription *entityDef = [[NSEntityDescription alloc] init];
[entityDef setName:entityName];
[entityDef setManagedObjectClassName:entityName];
[model setEntities:[NSArray arrayWithObject:entityDef]];
NSArray *properties = [CoreDataHelper CreateAttributes:attributes];
[entityDef setProperties:properties];
[entityDef release];
return TRUE;
但它会引发错误:
由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序, 原因:“无法修改不可变模型。” *** 第一次抛出调用堆栈: ( 0 核心基础 0x01c5abe9 __exceptionPreprocess + 185 1 libobjc.A.dylib 0x01daf5c2 objc_exception_throw + 47 2核心数据0x0152634a-[NSManagedObjectModel(_NSInternalMethods)_throwIfNotEditable]+106 3 核心数据 0x01526904 -[NSManagedObjectModel setEntities:] + 36 ……这似乎表明模型是只读的。
【问题讨论】:
警告:Core Data 不是 SQL。实体不是表格。对象不是行。列不是属性。 Core Data 是一个对象图管理系统,它可能会也可能不会持久化对象图,并且可能会或可能不会在幕后使用 SQL 来做到这一点。试图用 SQL 术语来思考 Core Data 会导致您完全误解 Core Data 并导致很多痛苦和浪费时间。 【参考方案1】:From the documentation:(重点是我的)
托管对象模型是可编辑的 直到它们被对象图使用 管理器(托管对象上下文或 持久存储协调器)。这 允许您创建或修改它们 动态的。但是,一旦模型 使用中,不得更改。 这是在运行时强制执行的——当 对象管理器首先获取数据 使用模型,整个模型 变得不可编辑。任何试图 改变一个模型或它的任何一个 该点之后的子对象会导致 要抛出的异常。 如果您需要 修改正在使用的模型,创建 副本,修改副本,,然后 丢弃旧物 型号。
【讨论】:
但是怎么做呢?我尝试新建模型并使用 NSPersistentStoreCoordinator 方法 'addPersistentStoreWithType:configuration:URL:options:error' 将模型保存为新的 sqlite 文件,但失败......【参考方案2】:我引用了 Apple 的文档,它非常准确地描述了它:
实体描述是可编辑的,直到 它们被对象图使用 经理。这允许您创建或 动态修改它们。然而,有一次 使用了描述(当 托管对象模型 属于与一个相关联 持久存储协调器),它必须 不能(确实不能)改变。这 在运行时强制执行:任何尝试 改变一个模型或它的任何一个 模型后的子对象 与持久存储相关联 协调器导致异常 抛出。如果您需要修改模型 正在使用中,创建副本,修改 副本,然后丢弃对象 使用旧模型。
【讨论】:
我们如何用新创建的模型替换旧模型?【参考方案3】:来自NSManagedObjectModel
的文档:
以编程方式编辑模型
托管对象模型是可编辑的 直到它们被对象图使用 管理器(托管对象上下文或 持久存储协调器)。这 允许您创建或修改它们 动态的。但是,一旦模型 使用中,不得更改。 这是在运行时强制执行的——当 对象管理器首先获取数据 使用模型,整个模型 变得不可编辑。任何试图 改变一个模型或它的任何一个 该点之后的子对象会导致 要抛出的异常。如果你需要 修改正在使用的模型,创建 副本,修改副本,然后 丢弃旧物 型号。
换句话说,在设置持久存储协调器或托管对象上下文之前编辑托管对象模型。
【讨论】:
嗨,可以为此目的显示一些代码吗?非常感谢【参考方案4】:如果你想动态创建实体请忽略CoreData,试试SQLite(请使用神奇的FMDB库),它不会让你失望的。
请注意,SQLite/FMDB 不支持 iCloud。
【讨论】:
以上是关于如何在 Core Data 模型中动态创建新实体(表)?的主要内容,如果未能解决你的问题,请参考以下文章