我有一个线程操作,创建一个新的管理对象,将其保存到持续性存储,然后通过新的VIA NSNotification反对主线程的objectID作进一步处理管理对象上下文不保存到持续性商店
但是,当我尝试从主线程访问新创建的托管对象时,我在后台线程上设置的所有值都返回为空。
**后台线程
// create a new managed object context for this thread
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:[appDelegate persistentStoreCoordinator]];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
// create the object
MyObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject" inManagedObjectContext:context];
[newManagedObject setAValue:@"A"];
[newManagedObject setBValue:@"B"];
[newManagedObject setCValue:@"C"];
// save it on the main thread
[context performSelectorOnMainThread:@selector(save:) withObject:nil waitUntilDone:NO];
// post notification to main thread, pass the objectID
NSMutableDictionary *userInfo = [NSDictionary dictionaryWithObject:[newManagedObject objectID] forKey:@"objectID"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"doneInsertingObject" object:userInfo];
[context release];
**主线程
...
// register notification for background thread
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeContextChanges:) name:NSManagedObjectContextDidSaveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomethingWithObject:) name:@"doneInsertingObject" object:nil];
...
- (void)doSomethingWithObject:(NSNotification*)noif
{
if([NSThread isMainThread] == NO)
{
// run this on the main thread
[self performSelectorOnMainThread:_cmd withObject:noif waitUntilDone:NO];
return;
}
// get managed object from objectID
NSDictionary *userInfo = [noif userInfo];
MyObject *object = (MyObject*)[appDelegate.managedObjectContext objectWithID:[userInfo valueForKey:@"objectID"]];
[appDelegate.managedObjectContext refreshObject:object mergeChanges:YES];
// these should return 'A, B, C' but all three return 'nil'
NSLog(@"aValue: %@", object.aValue);
NSLog(@"bValue: %@", object.bValue);
NSLog(@"cValue: %@", object.cValue);
}
// merge background thread moc with main moc
- (void)mergeContextChanges:(NSNotification *)notification
{
if([NSThread isMainThread] == NO)
{
// run this on the main thread
[self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
return;
}
// fault all updated objects
NSSet *updated = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for(NSManagedObject *thing in updated)
{
[[appDelegate.managedObjectContext objectWithID:[thing objectID]] willAccessValueForKey:nil];
}
// merge changes to the main managed object context
[appDelegate.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
// force processing of any pending changes
[appDelegate.managedObjectContext processPendingChanges];
}
我试图改变合并政策,没有什么区别。
我已经尝试将日志记录添加到上下文合并方法,并且我已经确认在调用主线程上的doSomethingWithObject:方法之后从后台线程接收到“插入”通知。
为什么我的数据没有更新到持久存储?
其实如果你看看https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html#//apple_ref/doc/uid/TP40003385它提到“在后台保存线程容易出错“,并且应尽可能在主线程中完成。 – 2012-02-03 18:25:28
你是否尝试过'[self performSelectorOnMainThread:_cmd withObject:noif waitUntilDone:YES];'当你合并上下文? – 2012-02-03 18:32:55
设置waitUntilDone:到“YES”确实解决了我使用的代码的问题。然而,我与那里有更多的具体信息是否是好的/不好的调用保存:从后台线程。如果这很好,我宁愿这样做。 – 2012-02-05 17:29:39