NSFetchedResultsController 导致 iPhone 3G 死机

Posted

技术标签:

【中文标题】NSFetchedResultsController 导致 iPhone 3G 死机【英文标题】:NSFetchedResultsController causes iPhone 3G to freeze 【发布时间】:2011-03-30 14:22:26 【问题描述】:

我有一个 UISearchDisplayController,它会在 searchBar 更改时修改 NSFetchRequest 的 NSPredicate。此获取请求与更新 searchResultsTableView 的 NSFetchedResultsController 相关联。

这些在 ios 设备上运行顺利 >= iPhone 3GS,但在 iPhone 3G 设备上却惨遭失败,因为一旦搜索栏内容发生轻微变化,用户界面就会完全冻结。即使持久存储中没有任何记录,也会发生这种情况。

实际上可以执行提取,因为应用程序不会因为 exit(-1) 而退出。

有人看到过这样的问题或知道如何处理这个问题吗?

(在 iOS 4.3SDK 上执行此操作,部署目标设置为 4.0。挂起的 iPhone 3G 在 OS 4.2.1 上。)


创建搜索 FRC 的代码:

-(NSFetchedResultsController *)searchFetchedResultsController 

if (__searchResults) 
    return __searchResults;


NSFetchRequest *fetchrequest = [[NSFetchRequest alloc] init];
[fetchrequest setEntity:[NSEntityDescription entityForName:@"Product" inManagedObjectContext:[[LBCCacheManager sharedLBCCacheManager] managedObjectContext]]];

[fetchrequest setFetchBatchSize:20];
[fetchrequest setPropertiesToFetch:[NSArray arrayWithObjects:@"title", @"slug", nil]];

NSSortDescriptor *recentSort = [NSSortDescriptor sortDescriptorWithKey:@"dealsCount" ascending:NO];
[fetchrequest setSortDescriptors:[NSArray arrayWithObject:recentSort]];

NSFetchedResultsController *fetchedcontroller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchrequest
                                                                                    managedObjectContext:[[LBCCacheManager sharedLBCCacheManager] managedObjectContext]
                                                                                      sectionNameKeyPath:nil 
                                                                                               cacheName:nil];

fetchedcontroller.delegate = self;

[__searchResults release], __searchResults = nil;
__searchResults = [fetchedcontroller retain];

[fetchedcontroller release];
[fetchrequest release];

return  __searchResults;

搜索栏更改时的代码:

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString 
if ([controller.searchBar.text length] > 0) 
    [self contentFilter:controller];

return YES;


-(void)contentFilter:(UISearchDisplayController *)controller 
    [[self searchFetchedResultsController].fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"title contains[c] %@", controller.searchBar.text]];

    NSError *error = nil;
    if (![[self searchFetchedResultsController] performFetch:&error]) 
        NSLog(@"ERROR");
        exit(-1);
    

【问题讨论】:

【参考方案1】:

似乎非规范化模型解决了这个问题。

不会再为老一代设备使用父实体执行 ManagedObjects。

【讨论】:

以上是关于NSFetchedResultsController 导致 iPhone 3G 死机的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?