滚动表时对Core数据进行提取请求

时间:2012-11-11 13:57:34

标签: objective-c ios xcode cocoa-touch core-data

以下是我在cellForRowAtIndexPath中调用的内容:

   NSManagedObjectContext *context = [[AppDelegate sharedAppDelegate] managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Favorites" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    NSPredicate *requestPredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(link like '%@')",articleLink]];
    [fetchRequest setPredicate:requestPredicate];

    [fetchRequest setFetchBatchSize:1];
    NSError *error = nil;
    NSUInteger count = [context countForFetchRequest:fetchRequest error:&error];
    NSLog(@"Count - %d", count);
    if (count == 0)
        return NO;
    else
        return YES;

基本上它会检查我的模型中是否存在某个项目。非常有用,但我认为在如此短的时间内提取如此多的获取请求有什么问题吗?

电池管理有任何问题,每次调用时都会从磁盘读取吗?

还有什么更好的吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

您不想在滚动时进行抓取。它会破坏你的滚动表现。

根据您提到的代码,您根据链接是否已存储,尝试对单元格执行某些操作。

我可能在加载视图控制器时预先执行该操作并将其存储在内存中,然后在滚动时检查该值。

答案 1 :(得分:1)

您正在做的事情有几个问题。首先,提取非常慢,因为它确实会读取磁盘上的持久存储。数据库越大,您的获取速度就越慢,查询(NSPredicate)变得越复杂。

其次,你无法控制调用cellForRowAtIndexPath的次数,你只能假设它在每个单元变为可见时被调用一次,但它也可能在其他情况下被调用。您也无法控制用户如何使用ScrollView,他可能会尝试像疯了一样滚动。该方法中的所有内容都必须尽可能高效,并且不能减慢主线程,否则ScrollView会不断冻结,这对用户来说非常糟糕。

第三,你经常分配和初始化新对象,在这种情况下是NSFetchRequests,这是昂贵的。缓存将大大提高您的性能,您应该尽可能避免分配新对象。尽管这已经是一个糟糕的例子,但fetchRequest可以很容易地存储为全局变量,并在每次获取之前更改其谓词。

从代码中我可以看出,似乎你有一个名为Favorite的实体,它包含一个链接,一个TableView显示链接,你想根据该链接是否是最喜欢的内容来改变你的单元格。

您应该做的是在首次加载ViewController时获取所有收藏夹,将所有链接存储在数组中,并在cellForRowAtIndexPath中检查该链接是否存在于该数组中。这样,当用户滚动ScrollView时,您只能从内存中读取内容并且性能最佳。