使用Coredata或NSMutableArray的NSPredicate进行过滤的最佳方法?

时间:2015-03-19 06:50:48

标签: ios core-data filter nsmutablearray nspredicate

在我的应用中,我使用CoreData来保存数据。我在我的一个viewController中有过滤器。与Sort by NSDatefilter by any value一样。在此视图控制器中,我UITableViewNSMutableArray填充并具有不同的过滤器按钮。首先,我从CoreData表中获取所有数据并存储到此NSMutableArray并执行[tableView reloadData]

现在执行过滤我正在使用NSPredicate。所以我的问题是,哪种方法可以做过滤。我应该将此谓词传递给NSFetchRequest,从CoreData表中获取所有数据并再次存储到数组中并执行重新加载表,或者我应该将其传递到数组中并重新加载。

哪一个是最快的并且消耗低内存。

2 个答案:

答案 0 :(得分:1)

这实际上取决于具体情况。

想象一下,您正在获取洛杉矶餐厅的评论。如果您希望用户过滤中国餐馆,然后过滤意大利餐馆,那么您可以更快地获取洛杉矶的所有餐厅(即不使用获取的谓词),但使用谓词生成对象数组并将结果传递给表视图。当用户过滤意大利餐馆时,您已经在结果数组中提供了数据,因此过滤它会很快。但是,在洛杉矶存储所有餐馆可能会导致结果数组太大而浪费内存。如果用户从不重新过滤数据,那么您无需获取该数据。

如果您希望生成的数据集很大,那么过滤提取更有意义(即只获取您需要的数据)。但是,如果用户重新填充意大利餐馆的数据,则必须再次获取,这将花费更多时间。

对于记忆和时间肯定存在权衡。哪一个更正确取决于数据和应用程序的可能用途......

答案 1 :(得分:1)

原谅我 - 这是iOS8之前的旧学校 - 仍在将应用从UISearchController升级到UISearchDisplayController

因此,请记住这一点,让我们从定义一些属性开始......

一个可变数组变量:

@property (nonatomic, retain) NSMutableArray *searchResults;

和几个字符串变量:

@property (nonatomic, strong) NSString *stringSearchBarText;
@property (nonatomic, strong) NSString *searchAttribute;

searchAttribute属性设置为在我的代码中启用控制器多态,但是您可以将其设置为Static或使用setter分配值。

然后使用此(iOS8之前)UISearchDisplayController委托方法:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    //  Set search predicate and filter array
    if (searchString && searchString.length) {
        [self setStringSearchBarText:searchString];
        NSPredicate *searchPredicate = nil;
        NSArray *fetchedObjects = nil;
        NSMutableArray *arrayResults = nil;

        [self.searchResults removeAllObjects];

         searchPredicate = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", self.searchAttribute, searchString];
         fetchedObjects = self.fetchedResultsController.fetchedObjects;
         arrayResults = [NSMutableArray arrayWithArray:[fetchedObjects filteredArrayUsingPredicate:searchPredicate]];
        [self setSearchResults:arrayResults];
    }
    //  Return YES to reload the search result table view
     return YES;
}

要更简单地回答您的问题,请不要再次提取,只需将已提取的数据放入NSMutableArray并使用便捷方法filteredArrayUsingPredicate:过滤该数据。更便宜,更容易。


此外,值得注意的是我们不应该害怕大型数据集,因为有许多机制可以控制您最初获取的数据集的大小。

对我来说,没有比在实用书架中出现的更好的解释 - "核心数据,第2版,iOS数据存储和管理,OS X和iCloud" (2013年1月)作者:Marcus S. Zarra,特别是第4章,标题为“性能调整”。

国际海事组织在核心数据方面的稳固教育名单中排名第一。