バックグラウンド
マルチスレッドCoreDataアプリケーション
NSTreeController
とNSOutlineView
バインディング付きバックグラウンドコンテキストでNSOperationに子オブジェクトを作成します
を使用してメインコンテキストにマージします
mergeChangesFromContextDidSaveNotification
問題
20個の子の作成操作をキューに入れると、マージが完了すると、アウトラインビューに約10〜15個の子オブジェクトしか表示されません。
最大同時操作を1に設定すると、完全に機能し、20人の子が表示されます。
質問
私がやろうとしていることは不可能ですか?コアデータがマージを正常に実行するのにどのように苦労するかがわかります。または、私のコードに問題がありますか?
コード
JGGroupController
-(id)init {
self = [super init];
queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:10]; // If this is 1, it works like a dream. Anything higher and it bombs.
return self;
}
-(IBAction)addTrainingEntryChild:(id)sender {
moc = [[NSApp delegate] managedObjectContext];
JGTrainingBase *groupToAddTo = [[tree selectedObjects] objectAtIndex:0];
for (NSUInteger i = 0; i < 20; i++) {
JGAddChildrenObjectOperation *addOperation = [[JGAddChildrenObjectOperation alloc] init];
[addOperation addChildObjectToGroup:[groupToAddTo objectID]];
[queue addOperation:addOperation];
}
}
JGAddChildrenObjectOperation-NSOperationサブクラス
-(id)addChildObjectToGroup:(NSManagedObjectID *)groupToAddToID_ {
groupToAddToObjectID = groupToAddToID_;
return self;
}
-(void)main {
[self startOperation];
JGTrainingBase *groupToAddTo = (JGTrainingBase *)[imoc objectWithID:groupToAddToObjectID];
JGTrainingBase *entryChildToAdd = [JGTrainingBase insertInManagedObjectContext:imoc];
[groupToAddTo addChildren:[NSSet setWithObject:entryChildToAdd]];
[imoc save];
[self cleanup];
[self finishOperation];
}
-(void)mergeChanges:(NSNotification *)notification {
NSManagedObjectContext *mainContext = [[NSApp delegate] managedObjectContext];
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
}
-(void)startOperation {
// Omitted - Manage isExecuting, isPaused, isFinished etc flags
imoc = [[NSManagedObjectContext alloc] init];
[imoc setPersistentStoreCoordinator:[[NSApp delegate] persistentStoreCoordinator]];
[imoc setUndoManager:nil];
[imoc setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[imoc setStalenessInterval:0];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:imoc];
}
-(void)finishOperation {
// Omitted - Manage isExecuting, isPaused, isFinished etc flags
}