簡體   English   中英

如何通過創建本地上下文將GCD與Core Data一起使用

[英]How to use GCD with Core Data by creating local context

我正在嘗試處理項目並將其與coredata和GCD一起存儲。 我正在將mainContext復制到localContext。 我還沒有進入合並部分,但它一直在崩潰我。 這是我的代碼:

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'而終止應用程序,原因:'*** Collection <__ NSCFSet:0x7fb5c30c3700>在枚舉時發生了變異。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM