2

来自http://goo.gl/MkV8V

您必须在将要使用的线程上创建托管上下文。如果您使用 NSOperation,请注意它的 init 方法是在与调用者相同的线程上调用的。因此,您不能在队列的 init 方法中为队列创建托管对象上下文,否则它与调用者的线程相关联。相反,您应该在 main(对于串行队列)或 start(对于并发队列)中创建上下文。

来自http://goo.gl/6CMO4

在 ConnectionDidLoading 方法中:

ParseOperation *parseOperation = [[ParseOperation alloc] initWithData:self.earthquakeData];
[self.parseQueue addOperation:parseOperation];
[parseOperation release];   // once added to the NSOperationQueue it's retained, we don't need it anymore

ConnectionDidiLoading 正在主线程上调用。现在在 ParseOperation::initWIthData 方法中,我们有这样的东西:(参见 ParseOperation.m 文件)

    // setup our Core Data scratch pad and persistent store
    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [self.managedObjectContext setUndoManager:nil];

    SeismicXMLAppDelegate *appDelegate = (SeismicXMLAppDelegate *)[[UIApplication sharedApplication] delegate];
    [self.managedObjectContext setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];

#

我的理解是这个 managedObjectContext 仍然是在主线程上创建的。

如果有人澄清或纠正我的理解,将不胜感激,因为 Apple 的示例代码不太可能不正确。

4

2 回答 2

0

在我看来你是对的。Apple 似乎在此示例代码中打破了自己的规则。然而,在实践中,这似乎并没有太多宣传,只要托管对象上下文仅在一个线程上使用,您就是安全的,无论上下文是在哪个线程上创建的。

于 2012-06-19T07:10:29.683 回答
0

好点在这里。似乎代码不正确(但也许我错了)。根据我的经验,您应该在 start 方法中创建上下文(例如),否则可能会发生一些奇怪的事情。

另一条规则是你不能NSManagedObject在踏板之间通过。NSManagedObjectID而是通过。在传递它们之前,您需要保存到磁盘。

这些规则已在 iOS 5 中强制执行。从 iOS 5 开始,您可以利用 Core Data 新 API 在私有队列(还有一个主队列)中创建上下文并在那里执行长时间运行的计算。此外,如果您NSManagedObject在线程之间传递,则会发生异常。

于 2012-06-17T22:30:10.163 回答