fetchedresultscontroller行为

时间:2012-02-04 06:59:05

标签: objective-c ios

我有一个按分段开关排序的表视图。我想通过NSNumericSearch对表进行排序,以便得到1,2,11,22而不是1,11,2,22。我正在使用Core Data。

如果我创建多个记录并且'color'属性保持不变(即所有'red'),则在改变长度时,长度的排序最初是正确的(1,2,11,22)。如果我然后切换到分段控件的另一个selectedSegmentIndex,例如'shape'或'length',我会在同一数据上得到一个错误的排序顺序(1,11,2,22)。

我认为fetchedResultsController应该通过调用tableView重新加载数据来重新计算数据。

我没有使用谓词。我已经尝试将缓存名称设置为nil而没有任何效果。我也尝试过deleteCacheWithName:虽然它可能需要在不同的位置。

一些代码:

- (NSFetchedResultsController *)fetchedResultsController{    
if (__fetchedResultsController != nil) {
    return __fetchedResultsController;
} 
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];

switch (segmentedControl.selectedSegmentIndex) {
    case 0:
        sortKey = @"color";
        break;
    case 1:
        sortKey = @"length";
        break;
    case 2:
        sortKey = @"smell";
        break;
    case 3:
        sortKey = @"shape";
        break;
    default:
        sortKey = @"color";
        break;
}
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:YES comparator:^(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }];
NSSortDescriptor *sortDescriptor2 = [NSSortDescriptor sortDescriptorWithKey:@"length" ascending:YES comparator:^(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor,sortDescriptor2, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:sortKey cacheName:@"Master"];

aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    abort();
}
return __fetchedResultsController;
}
- (IBAction)changeSegment:(id)sender {
switch (segmentedControl.selectedSegmentIndex) {
    case 0:
        sortKey = @"color";
        break;
    case 1:
        sortKey = @"length";
        break;
    case 2:
        sortKey = @"smell";
        break;
    case 3:
        sortKey = @"shape";
        break;
    default:
        sortKey = @"one";
        break;
}
self.fetchedResultsController = nil;
[self.tableView reloadData];
//[NSFetchedResultsController deleteCacheWithName:@"Master"];
}

任何人都可以帮助我第一次纠正这种行为,第二次错误排序吗?

1 个答案:

答案 0 :(得分:2)

来自NSFetchedResultsController文档:

  

修改获取请求   您不能简单地更改获取请求以修改结果。如果要更改提取请求,则必须:   如果您使用缓存,请将其删除(使用deleteCacheWithName :)。   通常,如果要更改提取请求,则不应使用缓存。   更改提取请求。   调用performFetch:

我看不出你在做什么。更改排序顺序等同于更改获取请求。

我也认为你对结果控制器的自动化有所了解。它会在模型​​更改时自动更新表(如果实现委托方法),而不是相反。从数据源方法访问时,您可能依赖于属性重新加载获取的结果控制器,我认为这不是一个好主意。

此外,如果您希望从头开始重建FRC,则分段控制操作方法上的switch语句无关紧要。我建议使用一个单独的方法来返回您的获取请求,该请求从您的FRC设置和分段控制操作方法调用,然后按照文档中的描述切换请求。