ManagedObjectContexts在不同的线程中 - 不同的对象引用

时间:2012-03-23 09:49:33

标签: ios5 nsmanagedobject nsmanagedobjectcontext background-process

我正在开发一个应用程序,其中与后端的同步不应阻止UI。 因此,我确实使用了许多MOC和那些通过其performBlock方法运行下载和导入的MOC(这将自动在后台线程中完成)。

我的背景MOC是作为主要moc的孩子而创建的:

context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:aConfiguration.context];
coordinator = aConfiguration.coordinator;
model = aConfiguration.model;
store = aConfiguration.store;
errorHandler = aConfiguration.errorHandler;

所以大多数工作到目前为止都很好,但是存在一个重大问题。 我下载文本和图像数据。所以在UI中我想首先显示文本然后,对于每个下载的图像,在这个下载的图像中淡入淡出。 通常没问题,下载程序完成图像下载并调用其委托(服务)ala

downloder:(id<Downloader) aDownloader didFinishDownloadImageItem: (id) aObjectWithImage

而aObjectWithImage是我的模型对象,带有新下载的图像。

代表会将对象放入通知中并发布此通知

NSDictionary *userInfo = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObject:aObjectWithImage]
                                                       forKeys:[NSArray arrayWithObject:EntityWithImageDownloadedNotificationInfoKeyEntity]];    
[[NSNotificationCenter defaultCenter] EntityWithImageDownloadedNotification object:self userInfo:userInfo];

这里开始出现问题。让我们说我的UIViewController会观察这些通知。收到一个后,他会搜索他的对象数组,以显示信息词典中的一个对象来更改图像。

你看到了问题吗?他永远不会找到这个对象!由于这个事实,最初这个对象是在后台线程中创建的,因此是另一个MOC,UIViewController的对象数组(主MOC)中的对象引用总是与通知发布的对象(后台MOC)不同。

我知道如何解决这个问题,发布通知的代表可以在其MOC(这是主要的)上搜索对象,但我有点不喜欢这个想法。我认为这没有错,因为服务还创建了后台线程,因此它知道委托方法中接收的所有对象都在后台线程的MOC内。

我可以更好地处理这个问题吗? 我真的很感激你的任何想法!

2 个答案:

答案 0 :(得分:0)

您使用的是什么并发类型?我猜你的背景MOC NSPrivateQueueConcurrencyType来自你所说的使用performBlock:来包装你的查询。你的主要线程MOC是否使用NSMainQueueConcurrencyType

我认为你想要像this answer中描述的那样做。在你的后台MOC块中,告诉你的主要MOC执行一个块,并通过它的对象ID传递托管对象。

您可能会问,主线程的MOC中是如何存在新的托管对象的?容易:你使背景MOC成为主线程MOC的孩子。当您在后台MOC上调用save时,它会将其新对象推送到其父MOC中,这是您的主要MOC。在你传递对象ID之前就这样做,你的对象就在那里。

答案 1 :(得分:0)

通过引用我假设你的意思是objectID。在您的子上下文中保存对象之前调用[moc ObtainPermanentIDsForObjects:error:]。然后进行保存,而不是使用临时ID进行持久化,它应该具有永久性ID,您的主要上下文将被提取。

我在某处读到它并不打扰获取永久ID,而是替换临时id。将此视为错误或功能。