我有一個線程操作,創建一個新的管理對象,將其保存到持續性存儲,然後通過新的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