在重复的上下文中编辑 NSManagedObject 以稍后合并它

发布于 2024-11-02 18:28:09 字数 1135 浏览 1 评论 0原文

当用户双击我的应用程序中的视图时,uipopovercontroller 会向他显示可以编辑的字段。 (很像在 iPad 日历应用程序中)

该视图表示一个 NS 托管对象。为了能够取消在 uipopovercontroller 中完成的操作,我的想法如下:

1)在我的视图控制器中为弹出窗口创建一个“editManagedObjectContext”,并为其提供在整个应用程序中使用的主上下文的持久存储协调器。

editContext = [[NSManagedObjectContext alloc] init];
[editContext setPersistentStoreCoordinator:[myContext persistentStoreCoordinator]];

2) 从新的“editContext”中获取点击视图(任务*)上表示的对象

task = [editContext objectWithID:[taskOrNilForNewTask objectID]];

3) 使用此任务执行所有编辑,当用户完成后,他可以:

  1. 取消整个编辑操作。这只会丢弃 editContext 并返回。
  2. 节省。这将通过 mergeChangesFromContextDidSaveNotification 合并 editcontext 与原始上下文: 从而将更改提交到原始上下文中的相应任务。

问题是 task = [editContext objectWithID:[taskOrNilForNewTask objectID]]; 导致对象出现故障。后来,当我尝试访问任务对象的属性时,我要么收到 BAD_EXC 错误,要么我的任务对象似乎是某种奇怪的类型,范围包括:CALayer、NSCFData……

我的想法是我可能必须首先保存原始上下文,但这会导致大约相同的错误。但由于我在创建 editContext 之前保存,我认为保存操作可以在另一个线程中完成,这可能是一个原因吗?

我只是无法理解我做错了什么,希望你们能提出一些建议。

我的方法基于 Apple 的 CoreDataBook 代码示例中的方法 (rootviewcontroller.m - (IBAction)addBook:)

When a user double taps a view in my application a uipopovercontroller presents him with the fields which he can edit. (Much like in the iPad calendar app)

The view represents a NSmanagedobject. To be able to cancel the operations done in the uipopovercontroller my idea was as follows:

1) create a "editManagedObjectContext" in my viewcontroller for the popover and give it the persistentstorecoordinator of my main context used throughout my app.

editContext = [[NSManagedObjectContext alloc] init];
[editContext setPersistentStoreCoordinator:[myContext persistentStoreCoordinator]];

2) fetch the object represented on the tapped view (Task*) from the new "editContext"

task = [editContext objectWithID:[taskOrNilForNewTask objectID]];

3) Use this task to do all the editing and when the user finishes he can either:

  1. Cancel the entire editing operation. This would just discard of the editContext and return.
  2. Save. This would than merge the editcontext with the original context through mergeChangesFromContextDidSaveNotification :
    Thus commiting the changes to the corresponding task in the original context.

Problem is task = [editContext objectWithID:[taskOrNilForNewTask objectID]];
results in a faulted object. And later on when I try to access the properties of a task object I get either the BAD_EXC error or my task object seems to be of some strange type ranging from: CALayer, NSCFData,...

My thought was that I might have to first save the original context, but that results in about the same errors. But since I saved just before I made the editContext I thought the save operation could be done in another thread and that could be a reason?

I just can't get my head around what I'm doing wrong and hope you guys can come up with some advice.

My approach was based on the approach in the CoreDataBook codesample from Apple (rootviewcontroller.m - (IBAction)addBook:)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清引 2024-11-09 18:28:09

您的问题是 objectWithID: 返回一个自动释放的对象,然后您将其存储在 ivar 中而不保留它。系统后来释放了它,要么你得到了一个给你 EXC_BAD_ACCESS 的垃圾,要么你在同一内存位置巧合地得到了一个不同的对象。您所描述的错误已经清楚地表明了这一点。

self.task 修复它的原因是因为属性 self.task 被声明为保留,因此通过属性分配会自动执行必要的保留。请注意,如果您不在 dealloc 中释放它,那么您将泄漏内存。

Your problem was that objectWithID: returns an autoreleased object, which you were then storing in an ivar without retaining it. The system later deallocated it, and either you wound up with a garbage that gives you EXC_BAD_ACCESS or you wound up coincidentally with a different object at the same memory location. The errors you described made this clear.

The reason self.task fixes it is because the property self.task is declared retain, so assigning through the property automatically does the necessary retain. Do note that if you are not releasing it in dealloc then you will be leaking memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文