Xcode:使用复杂谓词来过滤核心数据集

时间:2012-02-09 01:01:12

标签: xcode core-data ios5 nspredicate

编辑:我正在添加一个新的粗糙表模型以供评论。这是你的想法吗?

enter image description here

我仍在尝试为核心数据集制作搜索过滤器。我遇到了问题here,所以我正以不同的方式解决问题。

首先,我要做的是以下内容:

  1. 遍历所有对象(tableViewModel.items中的NSManageObject *对象)

  2. 提取每个“对象”的所有子实体对象,并根据搜索字词进行验证。

  3. 如果子实体中存在搜索词,则将'object'添加到'autoSearchResults'(如果它还不存在)

  4. 我的代码如下:

    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个对象,一个是person.name“me”,一个是“you”,另一个是“Mother”。所有其他字段在所有对象中都是空白的。

    现在,我正在停止查看为每次搜索选择了多少个对象。基本上,找到了searchText但忽略了它。也就是说,例程看到searchText包含“我”,但仍然添加一个实际文本为“你”的对象。

    我将不胜感激任何帮助..如果它有助于减少这个例子,请告诉我..

1 个答案:

答案 0 :(得分:2)

这段代码最令人震惊的错误是你实际上并没有使用你创建的谓词。为了针对谓词测试对象,在谓词上调用evaluateWithObject:,传入要测试的对象。

但是这仍然行不通,因为它不知道“peopleSet”和所有其他字符串是什么:你不能使用局部变量,就好像它是一个keypath。

最后,这种结构并没有真正利用谓词的力量;你正在使用像正则表达式这样的谓词。要实际过滤对象集合,请在集合本身上使用filteredSetUsingPredicate:等方法,而不是测试每个对象。

当然,这将要求您在托管对象模型上创建瞬态属性以存储连接的名称列表,但如果您正确执行此操作,则在执行此类过滤时会看到性能提升。 / p>