【问题标题】:How to use two or more NSFetchedResultsController?如何使用两个或多个 NSFetchedResultsController?
【发布时间】:2012-06-02 03:02:27
【问题描述】:

我的应用使用 CoreData。它有一个 UISegmentedControl 和一个表格视图。 UISegmentedControl 用于根据不同的标准更新 tableview。

UISegmentedControl 的第一个选项将在单个 tableview 部分中显示所有数据。所以我在 - (NSFetchedResultsController*)fetchedResultsController

中使用了以下代码
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
                                          managedObjectContext:[self managedObjectContext] 
                                          sectionNameKeyPath:nil
                                          cacheName:@"Root"];   

第二个选项将在多个表格视图部分显示数据。所以我需要 NSSortDescriptor 并设置 sectionNameKeyPath。

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"city" 
                                                             ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *frc = nil;
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                          managedObjectContext:[self managedObjectContext] 
                                          sectionNameKeyPath:@"city" 
                                          cacheName:@"Root"];

因为 sectionNameKeyPath 不同,每个都需要不同的 NSSortDescriptor,我假设我需要两个不同的 NSFetchedResultsController。

我用来重新加载tableview的代码:

- (void) touchDownAtSegmentIndex:(NSUInteger)segmentIndex{

NSPredicate *predicate;
NSError *error;    

[NSFetchedResultsController deleteCacheWithName:@"Root"];

if(segmentIndex == 0)
{

}
else if(segmentIndex == 1)
{

}
else
{
    return;
}

[[[self fetchedResultsController] fetchRequest] setPredicate:predicate];
[[self fetchedResultsController] performFetch:&error];
[[self tableView] reloadData];
}

任何人都可以向我提供一个使用两个 NSFetchedResultsController 的代码示例。 谢谢。

解决方案:

除了来自@iTukker 的想法,我在返回fetchedResultsController 之前添加了更多检查。如果不进行此项检查,此方法将返回fetchedResultsController,而不是执行switch .. case .. 语句。

- (NSFetchedResultsController*)fetchedResultsController {

.....
    if ((fetchedResultsController!= nil) && [self.segmentChanged isEqualToString:@"false"])
    return fetchedResultsController;
.....

    if (frc == nil) {
        switch (segmentendControl.selectedSegmentIndex) {
           case 0: {
               frc = ... //first frc
               [frc retain];
               break;
           }
           case 1: {
               frc = ... //second frc
               [frc retain];
               break;
           }
        }
    }

....

}

【问题讨论】:

    标签: objective-c core-data


    【解决方案1】:

    假设 frc 是控制器的实例变量,你会做的是这样的事情

    - (NSFetchedResultsController*)fetchedResultsController {
       if (frc == nil) {
          switch (segmentendControl.selectedSegmentIndex) {
             case 0: {
                 frc = ... //first frc
                 [frc retain];
                 break;
             }
             case 1: {
                 frc = ... //second frc
                 [frc retain];
                 break;
             }
          }
       }
    
       return frc;
    }
    

    当你的 segmentedController 的值发生变化时

    [frc release];
    frc = nil;
    [tableView reloadData];
    

    希望这是有道理的

    【讨论】:

    • 谢谢。我假设您的答案是使用一个 fetchedResultsController。我记得做过类似的事情。它仅在应用程序首次加载时有效。但是当 segmentedControl 单击时它没有响应。我把[tableView reloadData] 放入(void) touchDownAtSegmentIndex:(NSUInteger)segmentIndex{
    • 我注意到你在 fetchedResultsController 中使用 [frc retain]; 并在 segmentedController 更改时使用 [frc release]。我会试一试。谢谢。
    • 是的,一个frc,在你的viewsController .h中你有类似NSFetchedResultsController *frc的东西。我会使用事件 UIControlEventValueChanged 来重置 frc 并重新加载表数据。是的,您使用了 retain(当然,当不使用 ARC 时),因为您在 fetchedResultsController 方法中创建了一个新的 frc,而它是 nil。而且我还假设 f.i.在 numberOfSectionsInTableView 中:您确实返回 [self fetchedResultsController].sections
    • 要明确一点,这很重要,在您的所有 tableview 数据源回调(如 numberOfRowsInsetions 等)中,您始终使用 [self fetchedResultsController] 而不是直接引用 frc!
    • 它没有用。我把NSLog 放在(NSFetchedResultsController*)fetchedResultsController 里面。日志显示它只调用了一次。每次分段控件更改时,它都不会再次执行。也许我真的需要不止一个NSFetchedResultsController
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多