RestKit:在普通的旧Objective-C对象内映射的托pipe对象

序言:我使用的RestKit 0.21.0,但我也试过0.23.0。

我有一个简单的旧的Objective-C对象(我们称之为POOCO)包含一个NSManagedObject的映射。 似乎在对这个根POOCO执行GET请求时,托pipe对象是在mainQueueManagedObjectContext下创build的。

但是,当我对POOCO执行PUT时,当加载响应(响应是发送的对象的副本)时,托pipe子对象在临时NSManagedObjectContext下创build,其父对象是mainQueueManagedObjectContext

快速抛开RestKit中的重新获取:

如果请求完全由NSManagedObject实例组成, NSManagedObject使用(我认为) mainQueueManagedObjectContext来“重新获取”结果对象。 (IIRC,一旦所有对象映射完成,对象和子对象将全部从主MOC中重新获取,replace在用于映射的临时MOC上创build的对象。

这个重新写入是完成的(据我所知),因为当一个MOC得到dealloc ,它pipe理的所有pipe理对象变得无效 。 因此,我们重新获取MOC中的对象, myObjectManager.managedObjectStore保留强引用,以便在临时MOC消失后保持有效。

由于映射中的根对象是一个POOCO,所以它对pipe理对象的任何引用都不会被重新获取 ,所以它们仍然附着在临时MOC上,一旦映射完成就会失效。

有没有人遇到这样的问题? 有什么可以build议的最佳做法? 是否有可能告诉RestKit,“使用mainQueueManagedObjectContext重新获取这些托pipe对象”或类似的东西?

托pipe对象实例不能在线程之间传递,RestKit在后台线程上执行映射。 如果返回的对象是托pipe对象,那么它们将被转移到主线程中。 有人可能会认为嵌套的pipe理对象没有被切换到主线程,是RestKit中的一个bug /监督(你可以在github中提出这个问题)。

您可以要求RestKit使用主线程来执行某些操作(通过明确地创build操作并运行它们,虽然这并不包含所有内容),但是您确实不希望这样做。

所以,你的主要select是在你的容器对象中有一个方法,你可以在success块中调用这个方法,它通过包含的pipe理对象进行迭代并“重新访问”它们 – 因为你知道所有的对象都可以用objectWithID: ,并在主线程上调用success块。

这个问题实际上有一些关于RestKit何时执行重读的误解。 在问题描述的情况下,RestKit实际上在success返回RKRefetchingMappingResult一个实例。 调用该对象上的任何访问器(如arrayfirstObject )实际上都会执行重新访问。 错误的是我从来没有在RKMappingResult上调用任何这些方法。

我的假设是,由于我在PUT请求中发送的对象将成为操作的targetObject ,所以对象将通过RestKit就地更新。 这就是为什么我从来没有觉得有必要对RKMappingResult做任何事情。 这个假设在技术上不是错误的 ,但是一旦映射完成而不是使用RKMappingResult ,直接访问对象,我就跳过了重新调整的步骤。

我已经提出了一个在我已经提交给RestKit人员的问题中的这种行为的改变,以在某些情况下进行自动重新获取。

总结:

当使用RKManagedObjectRequestOperation (无论您是手动指定还是RestKit为您select此类)进行请求时,请始终确保您执行RKMappingResult以确保从正确的NSManagedObjectContext重新获取结果。