2015-09-03 18 views
3

我正在嘗試處理項目並將其與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>在枚舉時發生了變化。'

任何想法?我是否正確阻止資源?謝謝!

+1

核心數據中的限制支持已被棄用。您應該使用核心數據'performBlock' API來管理線程之間的同步。 –

回答

1

您無法更新後臺線程上的限制上下文,然後將管理對象結果傳遞迴主線程以執行另一次更新並保存上下文。所有更新和上下文保存都需要在後臺線程上完成。這是禁閉的含義,你需要遵守禁閉規則。

+0

我已更新我的代碼,但仍然崩潰。現在我得到這個錯誤:終止應用程序由於未捕獲的異常'NSGenericException',原因:'***集合<__ NSCFSet:0x7fb5c30c3700>在枚舉時發生了變化。請在原始帖子中查看我更新的代碼。謝謝! – ordinaryman09

相關問題