添加到关系后未在coredata中找到对象

bru*_*sas 6 core-data objective-c relationship nsfetchrequest ios

我在添加关系后获取对象时遇到问题.我第一次获取类别,总是找到,然后当我添加到关系时,找不到以下类别.

这种关系是一种Many-To-Many.

例:

  • 获取类别 categoryId = 10
  • 找到类别对象
  • 添加到父对象关系
  • 下一个对象
  • 如果几个类别相同id,则categoryId = 10找不到

    NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    
       [private setParentContext:self.model.context];
        __block NSError *error = nil;
    
        [private performBlockAndWait:^{
    
            GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:private];
            for (NSDictionary *dic in responseObject[@"response"]) {
    
                GPCategory *category;
    
               //The first time always found
                if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:private])) {
                    NSLog(@"Found");
                    [category addDealsObject:deal];
    
                } else {
                    NSLog(@"Not Found");
    
                }
    
            }
        }];
    
        NSError *PrivateError = nil;
        if (![private save:&PrivateError]) {
            NSLog(@"Unresolved error %@, %@", PrivateError, [PrivateError userInfo]);
            abort();
        }
    
        if (!error) {
            //Save on main moc
            [self.model saveWithErrorBlock:^(BOOL success, NSError *error) {
                if (!success) {
                    NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
                }
            }];
    
        } else {
            NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]);
        }
    
    Run Code Online (Sandbox Code Playgroud)

编辑:

解决了,我想我的问题是我忘了在每次迭代结束时保存主要上下文.

        NSManagedObjectContext *backgroundMOC = [self.model backgroundMOC:self.model.context];

        [backgroundMOC performBlockAndWait:^{

            for (NSDictionary *dic in responseObject[@"response"]) {

                GPDeal *deal = [EKManagedObjectMapper objectFromExternalRepresentation:dic withMapping:[GPDeal objectMapping] inManagedObjectContext:backgroundMOC];

                GPCategory *category;
                if ((category = [GPCategory MR_findFirstByAttribute:@"catId" withValue:dic[@"mainAttribute"] inContext:backgroundMOC])) {
                    NSLog(@"Found with mainAttribute %@", dic[@"mainAttribute"]);
                    [deal addDealCategoryObject:category];
                }

                if([backgroundMOC hasChanges]) {
                    NSError * error;
                    [backgroundMOC save:&error];

                    [self.model.context performBlockAndWait:^{
                        if([self.model.context hasChanges]) {
                            NSError * error;
                            [self.model.context save:&error];
                        }
                    }];
                }
            }
        }];
Run Code Online (Sandbox Code Playgroud)

Swi*_*ect 2

您可能缺乏保存 MOC 链的能力。private为了清楚起见,我用变量 name替换了关键字backgroundMOC

对于上面的问题,我只能假设该行在NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 技术上类似于:

- (NSManagedObjectContext *)backgroundMOC:(NSManagedObjectContext *)mainMOC
{
    NSManagedObjectContext * threadManagedObjectContext = [[NSManagedObjectContext alloc]
                             initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [threadManagedObjectContext setParentContext:mainMOC];
    [threadManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    return threadManagedObjectContext;
}
Run Code Online (Sandbox Code Playgroud)

作为 mainMOC传递self.model.context,带有 aself.model.context和 a setMergePolicy
同样,我必须假设这self.model saveWithErrorBlock在技术上与以下内容相同:

[mainMOC performBlockAndWait:^{
    if([mainMOC hasChanges]) {
        NSError * error;
        [mainMOC save:&error];
        // handle error
    }
}];
Run Code Online (Sandbox Code Playgroud)

backgroundMOC如果是这样, (您的参考)也应该这样说private

[backgroundMOC performBlockAndWait:^{
    if([backgroundMOC hasChanges]) {
        NSError * error;
        [backgroundMOC save:&error];
        // handle error
    }
}];
Run Code Online (Sandbox Code Playgroud)

换句话说,您希望确保您的backgroundMOCmainMOCsave 操作是从各自的线程执行的,并且performBlockAndWait.