Xcode: использование сложного предиката для фильтрации основного набора данных - PullRequest
0 голосов
/ 09 февраля 2012

РЕДАКТИРОВАТЬ: я добавляю новую грубую модель таблицы для комментариев.Это то, что вы имели в виду?

enter image description here

Я все еще пытаюсь разработать поисковый фильтр для основного набора данных.Я застрял здесь , поэтому я подхожу к проблеме по-другому.

Во-первых, я пытаюсь сделать следующее:

  1. Итерация по всем объектам (NSManageObject * объект в tableViewModel.items)

  2. Извлечение всех объектов subentity для каждого «объекта» и проверка по критерию поиска.

  3. Если поисковый термин существует в подразделе, то добавьте «объект» в «autoSearchResults» (если он там еще не существует)

Мой код выглядит следующим образом:

NSLog(@"%s", __FUNCTION__);

    NSMutableArray *startArray = [NSMutableArray array];
    NSMutableArray *filteredArray = [NSMutableArray array];

    for (NSManagedObject *object in tableViewModel.items) 
    {
        NSLog(@"1 ");

        NSSet *set1 = [object valueForKeyPath:@"people.name"];
        NSString *str1 = [[set1 allObjects] componentsJoinedByString:@", "];
        peopleSet = str1;

        NSLog (@"peopleSet is %@ ", peopleSet);

        NSLog(@"2 ");
        NSSet *set2 = [object valueForKeyPath:@"place.name"];
        NSString *str2 = [[set2 allObjects] componentsJoinedByString:@", "];        
        placeSet = str2;

        NSLog(@"3 ");
        NSSet *set3 = [object valueForKeyPath:@"keyword.name"];
        NSString *str3 = [[set3 allObjects] componentsJoinedByString:@", "];        
        keywordSet = str3;

        NSLog(@"4 ");
        NSSet *set4 = [object valueForKeyPath:@"type.name"];
        NSString *str4 = [[set4 allObjects] componentsJoinedByString:@", "];        
        typeSet = str4;     

        NSLog(@"5 ");
        NSSet *set5 = [object valueForKeyPath:@"symbol.name"];
        NSString *str5 = [[set5 allObjects] componentsJoinedByString:@", "];        
        symbolSet = str5;

        NSLog(@"6 ");

        NSLog (@"searchText is: %@ ", searchText);

        myPredicate = [NSPredicate predicateWithFormat:@"(peopleSet contains[cd] %@) || (placeSet contains[cd] %@) || (keywordSet contains[cd] %@) || (typeSet contains[cd] %@) || (symbolSet contains[cd] %@)", searchText, searchText, searchText, searchText, searchText ];

        NSLog(@"7 ");       
        if (myPredicate) {
            [startArray addObject:object];
            NSLog (@"startArray.count is %i ", startArray.count);
        }

        NSLog(@"8 ");
        NSLog (@"startArray.count is %i ", startArray.count);
        /*
        if (startArray.count == 0)
        {
            NSLog(@"0");
        } else {            
            NSLog(@"9 ");
            [filteredArray addObject: startArray];
            NSLog(@"10 ");
            [startArray removeAllObjects];
            NSLog(@"11 ");
        }
        */

    }       


    //autoSearchResults = filteredArray;
    return autoSearchResults;
}

В моем тестировании у меня есть 3 объекта, один с личным именем "я", один с "вами" и один с "матерью".Все остальные поля являются пустыми во всех объектах.

Сейчас я остановлюсь, чтобы увидеть, сколько объектов выбрано для каждого поиска.По сути, searchText найден, но игнорируется.То есть подпрограмма видит, что searchText содержит, например, «я», но все равно добавляет объект, где фактический текст - «вы».

Я был бы признателен за любую помощь.пример, пожалуйста, дайте мне знать ..

1 Ответ

2 голосов
/ 09 февраля 2012

Наиболее вопиющая ошибка в этом коде заключается в том, что вы на самом деле не используете созданный вами предикат. Чтобы проверить объект по предикату, вызовите evaluateWithObject: для предиката, передав объект для проверки.

Но это все равно не сработает, потому что он не знает, что такое peopleSet и все остальные строки: вы не можете использовать локальную переменную, как если бы это был путь к ключу.

Наконец, эта структура на самом деле не использует преимущества предикатов; вы используете предикат как регулярное выражение. Чтобы фактически отфильтровать коллекцию объектов, используйте метод, такой как filteredSetUsingPredicate:, на самой коллекции вместо тестирования каждого объекта.

Конечно, это потребует от вас создания временного свойства в вашей модели управляемых объектов для хранения составного списка имен, но если вы сделаете это правильно, вы увидите повышение производительности при выполнении такого рода фильтрации.

...