我在這樣定義上的NSManagedObjectContext一個GCD調度隊列做業務:NSSortDescriptor背景後工作不保存
- (NSManagedObjectContext *)backgroundContext
{
if (backgroundContext == nil) {
self.backgroundContext = [NSManagedObjectContext MR_contextThatNotifiesDefaultContextOnMainThread];
}
return backgroundContext;
}
MR_contextThatNotifiesDefaultContextOnMainThread
是MagicalRecord方法:
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:[NSManagedObjectContext MR_defaultContext]];
return context;
後提取我的對象,並給他們正確的隊列位置,我登錄他們,順序是正確的。然而,第二個日誌似乎是完全隨機的,排序描述符顯然不起作用。
我已將問題範圍縮小到[self.backgroundContext save:&error]
。保存後臺上下文後,排序描述符被破壞。
dispatch_group_async(backgroundGroup, backgroundQueue, ^{
// ...
for (FooObject *obj in fetchedObjects) {
// ...
obj.queuePosition = [NSNumber numberWithInteger:newQueuePosition++];
}
NSFetchRequest *f = [NSFetchRequest fetchRequestWithEntityName:[FooObject entityName]];
f.predicate = [NSPredicate predicateWithFormat:@"queuePosition > 0"];
f.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"queuePosition" ascending:YES]];
NSArray *queuedObjects = [self.backgroundContext executeFetchRequest:f error:nil];
for (FooObject *obj in queuedObjects) {
DLog(@"%@ %@", obj.queuePosition, obj.title);
}
if ([self.backgroundContext hasChanges]) {
DLog(@"Changes");
NSError *error = nil;
if ([self.backgroundContext save:&error] == NO) {
DLog(@"Error: %@", error);
}
}
queuedObjects = [self.backgroundContext executeFetchRequest:f error:nil];
for (FooObject *obj in queuedObjects) {
DLog(@"%@ %@", obj.queuePosition, obj.title);
}
});
我有不知道爲什麼排序描述符不能正常工作,任何核心數據專家想幫幫忙?
更新:
不會發生此問題上的iOS 4,我想原因是在線程隔離和專用隊列模式之間的區別的地方。 MagicalRecord自動使用似乎行爲不同的新併發模式。
更新2:
的問題已經解決了通過添加保存的背景歷境的:
if ([[NSManagedObjectContext MR_contextForCurrentThread] hasChanges]) {
DLog(@"Changes");
NSError *error = nil;
if ([[NSManagedObjectContext MR_contextForCurrentThread] save:&error] == NO) {
DLog(@"Error: %@", error);
} else {
NSManagedObjectContext *parent = [NSManagedObjectContext MR_contextForCurrentThread].parentContext;
[parent performBlockAndWait:^{
NSError *error = nil;
if ([parent save:&error] == NO) {
DLog(@"Error saving parent context: %@", error);
}
}];
}
}
更新3:
MagicalRecord提供的方法以遞歸方式保存現在我的代碼看起來像這樣:
對我恥辱首先不使用它...
不過,我不知道爲什麼這幫助並希望得到一個解釋。
感謝您的輸入,我只嘗試了更多的線程隔離,但我更願意在iOS 5上使用專用隊列。在測試期間,我認爲我發現了一個錯誤。父上下文的保存會在子上下文的線程中調用,這會在從GCD上下文遞歸保存時導致問題。我已提交合並請求:https://github.com/magicalpanda/MagicalRecord/pull/159 – tim 2012-04-13 12:00:05