我理解这两个调用之间记录的差异.但是,有人知道我注意到以下观察到的行为的原因:
如果我有一个parentContext和一个临时的childContext,我使用childContext来编辑,插入和删除对象,如果使用[childContext objectWithID:objectID]; 为了检索存在于父上下文中的已知现有托管对象,它有时会给我一个带有故障的对象,在被触发时失败并生成异常.我理解objectWithID:在设计中,无论是否存在给定objectID的实际managedObject,它总是会返回一个处于故障状态的对象.但是,如果对象实际存在于父上下文中,我希望当访问任何属性时,将始终从父上下文成功检索对象(例如,将触发错误)而没有任何问题.如果我使用[childContext existingObjectWithID:objectID]; 我发现它确实总能成功.
为了记录,我已经关闭了子上下文的缓存,并且在调用[childContext resetContext]之后发生了同样的行为 - 因此它不是悬挂的旧缓存数据的人工制品,与父上下文不一致.
在我看来,单独的文档不足以解释这种行为.我当然可以将它用于体验,并且只是说"我现在知道总是使用existingObjectWithID:当将对象ID传递给我的子编辑上下文执行块时"但我感到不安并且想要确切地了解这里发生了什么(不是至少所以我可以理解,如果使用一个相对于另一个有任何性能影响,但也了解约束是什么,所以我可以确保没有一些不好的做法,我在我的代码中不必要地实现,然后使用错误或低效的调用来修复它).
我在自己的代码中看到了这种行为(堆栈跟踪来自火星,花了很长时间才找到问题的原因),并且我的解决方案是相同的(从使用 objectWithID: 在子上下文中移动到使用现有对象WithID:)。
就我而言,我会在父上下文中创建一个对象,立即为其获取永久对象 ID,并使用 UIManagedDocument 的 updateChangeCount:UIDocumentChangeDone 请求保存,这将在将来的某个时间安排保存。我认为这一点是讨论的关键。
然后,我将执行网络调用来获取与新创建的对象相关的 XML 数据,并解析该数据并将其导入到 Core Data 中。这发生在后台线程上,我将对象 ID 传递给该线程,该线程使用线程限制的子导入上下文。
在 iOS5 下,我会在工作线程中使用 objectWithID: 将新对象错误地放入导入上下文中。工作正常,没有任何问题。
在 iOS6 下,这开始失败,并出现奇怪的堆栈跟踪,唯一的解决方案是转移到existingObjectWithID:。在测试中,这种改变似乎是一个可靠的解决方案。
和你一样,我也试图找到一些明确的说法来解释为什么它会起作用,但我没有成功。然而,我认为我的代码所展示的模式和我看到的堆栈跟踪也许可以解释正在发生的事情。我总是看到尝试从持久存储中获取数据时发生崩溃。我相信在 iOS5 下,我通过 UIManagedDocument 请求的保存是在我的子线程有机会运行之前发生的,因此在我调用 objectWithID: 之前新对象已被持久化。从我的崩溃日志来看,iOS6 下并非如此;线程在对象进入持久存储之前运行,因此还无法将其提取到子上下文中。我的假设是,existingObjectWithID: 确保在尝试提取之前执行任何挂起的 SQL I/O,因此当提取发生在我的工作线程中时,持久存储是一致的。我一直无法找到任何明确的证据来支持这一点,但广泛的测试似乎支持这就是正在发生的事情。
| 归档时间: |
|
| 查看次数: |
1432 次 |
| 最近记录: |