我正在嘗試處理項目並將其與coredata和GCD一起存儲。我將mainContext複製到localContext。我還沒有到達合併的部分,但它一直在撞我。這裏是我的代碼:如何通過創建本地上下文將GCD與Core Data一起使用
dispatch_queue_t coreQueue = dispatch_queue_create("coreQueue", DISPATCH_QUEUE_CONCURRENT);
NSMutableSet __block *sumManagedObjects=[NSMutableSet set];
int processorCount = (int) [[NSProcessInfo processInfo] processorCount];
int __block limit = ceil((float)recordsToCreate.count/processorCount);
int loopCount = ceil((float)recordsToCreate.count/limit);
dispatch_apply(processorCount, coreQueue, ^(size_t i) {
int startIndex = ((int)i)*limit;
int maxIndex = (int)recordsToCreate.count;
int endIndex = (startIndex + limit) < maxIndex ? (startIndex + limit) : maxIndex;
int range = endIndex - startIndex;
NSManagedObjectContext *localContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[localContext setParentContext:self.mainContext];
NSSet *createdObjects= [localContext insertWithEntityName:self.entityName withDataObjects:[NSSet setWithArray:[recordsToCreate subarrayWithRange:NSMakeRange(startIndex, range)]]];
dispatch_async(dispatch_get_main_queue(), ^{
[sumManagedObjects unionSet:createdObjects];
NSLog(@"managed objects %tu start index %d end index %d size_t : %d, sum managed object : %tu thread %@", [createdObjects count], startIndex, endIndex, (int)i, [sumManagedObjects count], [NSThread currentThread]);
if([sumManagedObjects count] == recordsToCreate.count) {
[sumManagedObjects setValue:@YES forKey:ItemAttribute.someKey];[context save:nil];
}
});
下面是更新後的代碼:
dispatch_queue_t coreQueue = dispatch_queue_create("coreQueue", DISPATCH_QUEUE_CONCURRENT);
NSMutableSet __block *sumManagedObjects=[NSMutableSet set];
int processorCount = 8;
int __block limit = ceil((float)recordsToCreate.count/processorCount);
int loopCount = ceil((float)recordsToCreate.count/limit);
NSLog(@"int count %d, record to create %tu", loopCount, recordsToCreate.count);
dispatch_apply(processorCount, coreQueue, ^(size_t i) {
int startIndex = ((int)i)*limit;
int maxIndex = (int)recordsToCreate.count;
int endIndex = (startIndex + limit) < maxIndex ? (startIndex + limit) : maxIndex;
int range = endIndex - startIndex;
NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateManagedObjectContext setPersistentStoreCoordinator:self.mainContext.persistentStoreCoordinator];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(managedObjectContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:privateManagedObjectContext];
[privateManagedObjectContext insertWithEntityName:self.entityName withDataObjects:[NSSet setWithArray:[recordsToCreate subarrayWithRange:NSMakeRange(startIndex, range)]]];
NSLog(@"current thread %@ start index %tu end index %tu size_t : %d", [NSThread currentThread], startIndex, endIndex, (int)i);
dispatch_async(dispatch_get_main_queue(), ^{
if(self.cancelled) return;
[privateManagedObjectContext performBlockAndWait:^{
NSError *error = nil;
privateManagedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
BOOL success = [privateManagedObjectContext save:&error];
if (!success) {
NSLog(@"%@", error);
}
}];
});
});
- (void)managedObjectContextDidSave:(NSNotification *)notification {
[self.mainContext performBlockAndWait:^{
if(self.cancelled) return;
dispatch_async(dispatch_get_main_queue(), ^{
if(self.cancelled) return;
[self.mainContext mergeChangesFromContextDidSaveNotification:notification ];
});
}];}
現在,我得到這個錯誤: 終止應用程序由於未捕獲的異常「NSGenericException」,原因:「***收藏< __NSCFSet:0x7fb5c30c3700>在枚舉時發生了變化。'
任何想法?我是否正確阻止資源?謝謝!
核心數據中的限制支持已被棄用。您應該使用核心數據'performBlock' API來管理線程之間的同步。 –