NSFetchedResultsController自定义排序未被调用

时间:2011-01-25 03:47:01

标签: iphone objective-c cocoa-touch core-data nsfetchedresultscontroller

我目前正在尝试使用NSFetchedResultsController从Core Data填充我的项目中的UITableView。我正在使用带比较器的自定义搜索(虽然我也尝试了选择器并遇到了相同的问题):

    if (fetchedResultsController != nil) {
        return fetchedResultsController;
    }

    /*
     Set up the fetched results controller.
    */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES comparator:^(id s1, id s2) {
            NSLog(@"Comparator");
      //custom compare here with print statement
    }];
    NSLog(@"Sort Descriptor Set");
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstLetterOfObject" cacheName:@"Objects"];
    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
    if (![fetchedResultsController performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return fetchedResultsController;

当我进入此选项卡时,我已经记录了整个程序并发现NSFetchedResultsController在获取时甚至没有进入比较器块。它用一些默认的排序方法对它进行排序。

但是,如果我删除并添加一个带有objectName的Object,则会输入比较器块并正确对表进行排序。

为什么NSFetchedResultsController在更改托管对象模型之前不使用比较器进行排序?

注意:我已经尝试过关闭缓存,和/或在viewDidLoad:中执行提取,但似乎我提取的次数并不重要,但是什么时候。出于某种原因,它只在对象模型被更改后才使用我的排序。

3 个答案:

答案 0 :(得分:8)

我可以想到几件事。首先,尽管这可能不是您的问题,但您无法对瞬态属性进行排序。但更可能的是,当在由SQL存储支持的模型中进行排序时,比较器被“编译”为SQL查询,而不是所有的Objective-C函数都可用。在这种情况下,您需要在执行提取后在内存中进行排序。

编辑:请参阅此doc,特别是“获取谓词和排序描述符”部分。

答案 1 :(得分:1)

我看到同样的问题,解决它的方法是修改一个对象,保存更改然后将其恢复到原始值并再次保存。

    // try to force an update for correct initial sorting bug
NSInteger count = [self.fetchedResultsController.sections count];
if (count > 0) {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0];
    count = [sectionInfo numberOfObjects];
    if (count > 0) {
        NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
        NSString *name = [obj valueForKey:@"name"];
        [obj setValue:@"X" forKey:@"name"];
        // Save the context.
        [self saveContext];
        [obj setValue:name forKey:@"name"];
        // Save the context.
        [self saveContext];
    }
}

答案 2 :(得分:0)

抱歉,您是否错过了代码段的最终获取部分?:

NSError *error;
BOOL success = [aFetchedResultsController performFetch:&error];

不要忘记发布请求:

[fetchRequest release];