ПредикатWithFormat возвращает неправильный объект данных Core - PullRequest
0 голосов
/ 25 октября 2018

Мое приложение содержит объект изображения, который он получает с сервера и размещает в основных данных.Каждый объект содержит image = NSData imageId = NSString и imageKeyword = NSString Чтобы проверить, были ли удалены какие-либо изображения с сервера, приложение получает массив image_id, который сравнивается с image_ids, содержащимся в приложении, и удаляет любые изображения, которые не являютсянайдено в массиве с сервера.

Метод использует NSPredicate, чтобы найти, найден ли imageId в allImageArray, который приложение получает от сервера.Не найденные объекты добавляются в массив 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.

Пример из журнала удаленного объекта.Как уже упоминалось, ImageId = 25245 находятся в allImageArray с сервера и удаляются, только когда я добавляю слово в 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 голосов
/ 01 декабря 2018
-(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 и используйте localContext.Когда saveWithBlock завершится, он объединит 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];

        }
    }];
    }
}  

Вероятно, вам следует прочитать документы MagicalRecord и Apple о NSManagedObjectContext.Удачи!

...