predicateWithFormat返回错误的核心数据对象

时间:2018-10-25 13:03:06

标签: ios objective-c magicalrecord

我的应用程序包含它从服务器接收的图像对象,并且存储在Core数据中。每个对象都包含image = NSData imageId = NSString和imageKeyword = NSString 为了检查是否已从服务器中删除任何图像,应用程序将接收一个image_id数组,该数组与应用程序中包含的image_ids进行比较,并从服务器中删除该数组中找不到的任何图像。

该方法使用NSPredicate查找是否在应用程序从服务器接收的allImageArray中找到了imageId。找不到的对象将添加到imageToDelete数组,然后从核心数据中删除。只要对象仅包含imageId和image,此方法就可以正常工作。

-(void)updateLocalImagesFromActivitiesParents:(NSArray*)allImageArray
{
    NSPredicate *imageIdsFilter = [NSPredicate predicateWithFormat:@"NOT (imageId IN %@)", allImageArray];
    NSFetchRequest *imageIdsRequest = [ImageCD MR_requestAllWithPredicate:(NSPredicate *)imageIdsFilter];
    NSArray *imagesToDelete = [ImageCD MR_executeFetchRequest:imageIdsRequest];


    if([imagesToDelete count] > 0){
    [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext){

        for(ActivityCD *imageToDelete in imagesToDelete){
            [imageToDelete MR_deleteEntityInContext:localContext];
            [localContext MR_saveToPersistentStoreAndWait];

        }
    }];
    }
}

但是我注意到,每次我为imageKeyword分配一个值时,上述方法检测到在allImageArray中都找不到并删除它。我很难理解为什么会发生这种情况,因为delete方法应该只查找imageid,但似乎也可以检测到imageKeyword中的更改。

已删除对象的日志中的样本。如前所述,在服务器的allImageArray中可以找到ImageId = 25245,并且只有在将“ word”添加到imageKeyword时才将其删除。

"<ImageCD: 0x600003464c80> (entity: ImageCD; id: 0xa0c6b9257bed7492 <x-coredata://6454DD11-CEDB-40C2-B5E0-1FEE8006EE92/ImageCD/p26> ; data: {\n    image = <89504e47 0d0a1a0a 0000000d 49484452 00000280 00000203 08020000 001b8b38 02000020 00494441 54789c84 bd4982e5 b8ae>;\n    imageId = 25245;\n    imageKeyword = word;\n})"

这是我将imageKeyWord分配给对象的方法。

-(void)setImageKeyWord
{
    ImageCD *localImage = [ImageCD MR_findFirstByAttribute:@"imageId" withValue:[NSString stringWithFormat:@"%@", _choosenImageId]];

    [MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {

    localImage.imageKeyword = _userCreate;


    }];
    [self testingKeyWordSearch];

}

我猜我在某种程度上给imagKeyWord分配了错误,但是我不知道怎么做。希望得到一些支持:)

1 个答案:

答案 0 :(得分:0)

-(void)setImageKeyWord
{
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext * _Nonnull localContext) {
        ImageCD *localImage = [ImageCD MR_findFirstByAttribute:@"imageId"
                                                     withValue:[NSString stringWithFormat:@"%@", _choosenImageId]
                                                     inContext:localContext];
        localImage.imageKeyword = _userCreate;
    }];
    [self testingKeyWordSearch];
}

在您的代码中,您呼叫findFirstByAttribute。 它在ImageCD上返回defaultContext的实例。

更改imageKeyword的值时,您正在defaultContext上对其进行更改。 localContext中可用的saveWithBlock中没有。

saveWithBlock完成后,您什么都没有保存!下次defaultContext将您的更改保存到localImage时将保留。

容易修复。只需在findFirstByAttribute中调用saveWithBlock并使用localContextsaveWithBlock完成后,它将localContext合并到defaultContext中。

为了安全起见,我将更改您的第一段代码,以便所有获取和删除操作都在同一上下文中:

-(void)updateLocalImagesFromActivitiesParents:(NSArray*)allImageArray
{
    NSPredicate *imageIdsFilter = [NSPredicate predicateWithFormat:@"NOT (imageId IN %@)", allImageArray];

    if([imagesToDelete count] > 0){
    [MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext){

        NSFetchRequest *imageIdsRequest = [ImageCD MR_requestAllWithPredicate:(NSPredicate *)imageIdsFilter inContext:localContext];
        NSArray *imagesToDelete = [ImageCD MR_executeFetchRequest:imageIdsRequest inContext:localContext];

        for(ActivityCD *imageToDelete in imagesToDelete){
            [imageToDelete MR_deleteEntityInContext:localContext];
            [localContext MR_saveToPersistentStoreAndWait];

        }
    }];
    }
}  

您可能应该阅读有关NSManagedObjectContext的MagicalRecord和Apple文档。祝好运!