【问题标题】:Create an NSManagedObject Without Saving? [duplicate]创建一个 NSManagedObject 而不保存? [复制]
【发布时间】:2012-04-27 08:07:07
【问题描述】:

可能重复:
Store But Don't Save NSManagedObject to CoreData?

我需要创建一个 NSManagedObject 而不保存它,我该怎么做?

我想这样做的原因是应用程序有一个设置,用户可以在其中输入他们的详细信息,但是我只想在他们完成设置后保存对象(他们可以选择取消,在这种情况下对象需要被丢弃而不被保存,这就是我不想立即插入的原因。

我尝试过在没有上下文的情况下插入一个,但应用程序崩溃了。

我尝试了以下方法:

GuestInfo *guest;
guest = (GuestInfo *)[NSEntityDescription insertNewObjectForEntityForName:@"GuestInfo" inManagedObjectContext:nil];

这会导致崩溃并显示以下错误消息:

'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'GuestInfo''

【问题讨论】:

  • 为什么不向我们展示您的代码?
  • 如果你不需要持久化这个对象,你实际使用它的目的是什么?你不能只创建另一个具有相同接口的对象吗?
  • 如果你想插入一个 NSManagedObject 那么你需要有一个上下文来把它放进去。但是,我同意@Paul.s
  • 我想这样做的原因是应用程序有一个设置,用户可以在其中输入他们的详细信息,但是我只想在他们完成设置后保存对象(他们可以选择取消,在这种情况下,对象需要被丢弃而不被保存,这就是我不想立即插入它的原因。

标签: ios objective-c core-data nsmanagedobject nsmanagedobjectcontext


【解决方案1】:

创建一个 NSManagedObjectContext,作为普通上下文的子级。您可以在其中进行所有您想要的更改,只要您不调用 save,那里的内容就不会被推送。

例如...

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
moc.parentContext = myCurrentManagedObjectContext;

现在,您可以在程序的任何线程中进行以下调用...

[moc performBlock:^{
    // Do anything you want to with this context... make a new object, whatever.
    // As long as you do not call [moc save], your changes will not propagate
    // up to the parent context, nor saved.
}];

【讨论】:

  • 原谅我,我是 CoreData 的新手,我已经尝试了第一个,但我崩溃了:'Parent NSManagedObjectContext must use either NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType.'。然后,尝试该方法我得到一个错误,说在声明 performWork 的上下文中没有可见接口。
  • 那么您需要提供更多信息。具体来说,您是如何创建“当前”的 MOC 的?如果您仅使用 alloc/init 来执行此操作,请尝试使用 alloc/initWithCurrencyType: NSMainQueueConcurrencyType 创建它,如果您的应用程序仅使用主线程,那将很好。关于 performWork.. 类型。我在答案中修复了它。
  • This. 使用私有上下文创建可能是暂时的托管对象比将对象插入主上下文然后在不需要时将其删除(如当前接受的答案表明)。除了简洁的设计之外,您还可以从这种方法中获得许多其他好处。
【解决方案2】:

如果您不想保存 Core Data 对象,则创建它有点奇怪....但无论如何,错误表明您的项目中没有名为 GuestInfo 的模型文件。验证它是否存在并包含在您的复制捆绑资源部分中。模型文件是您在数据库中声明类型以及它们之间的连接的文件。

【讨论】:

  • 这个错误的原因实际上是insertNewObjectForEntityForName:inManagedObjectContext:方法从它的上下文参数推断模型(这里是nil)。这并不一定意味着模型文件不存在。
  • @omz 我的意思是它不存在于正在寻找的表单中......但我承认我确实忽略了上下文是 nil ^^;
【解决方案3】:

托管对象总是需要有一个上下文。如果您不希望对象持久化,只需不要保存上下文。

如果你从不希望你的对象是持久的,那么你是否应该真正使用 Core Data 是值得怀疑的。

【讨论】:

  • 如果我必须始终使用上下文,那么为什么在调用 insertNewObjectForEntityForName:inManagedObjectContext: 时它会立即将对象添加到 CoreData 中并使用空值?我想创建对象但不保存它,除非用户稍后确认。
  • 所以?在托管对象上下文中插入对象不会 保存它。您必须通过调用 save: 来明确执行此操作。
  • 我认为这是错误的?当我使用 insertNewObjectForEntityForName:inManagedObjectContext 然后(在调用保存之前!)对 coredata 执行提取时,对象会显示出来。
  • @KevinGrabher 获取请求可以返回尚未保存的对象。引用NSManagedObjectContext docs:“如果执行获取请求,则会检索满足请求(...)指定的标准并且已插入上下文但尚未保存到持久存储的对象在这种情况下。”
【解决方案4】:

我建议创建托管对象并照常插入托管对象上下文。您将获得对托管对象的引用,即:

GuestInfo* guest = (GuestInfo *)[NSEntityDescription insertNewObjectForEntityForName:@"GuestInfo" inManagedObjectContext:managedObjectContext];

然后如果用户取消,只需将其从托管对象上下文中删除,如下所示:

[guest deleteInContext:managedObjectContext];

托管对象上下文被设计为一个便签本,您可以像这样在其中创建和删除对象。

您可能会考虑的另一个选项是调用:

[managedObjectContext rollback]

如果用户取消。即,您将在托管对象上下文中创建托管对象,但如果用户取消,您将撤消或回滚托管对象上下文的状态到上次保存时的状态。请参阅 Apple 的“使用托管对象”文档的“撤消管理”部分:

https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/Articles/cdUsingMOs.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多