如何使用NSFetchedResultsController按字母顺序对UITableView进行排序?

时间:2011-04-14 08:22:19

标签: iphone cocoa-touch uitableview nsfetchedresultscontroller nssortdescriptor

当用户按“按字母顺序排序”时,我为我的表调用以下方法:

- (void) sortByName
{
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    NSMutableArray *items = [[fetchedResultsController fetchedObjects] mutableCopy];
    [items sortUsingDescriptors:sortDescriptors];

    int newDisplayOrder = 0;

    for (NSManagedObject *managedObject in items)
    {
        [managedObject setValue:[NSNumber numberWithInt:newDisplayOrder++ ] forKey:@"displayOrder"];
    }

    [sortDescriptor release];
    [sortDescriptors release];

    // Save the context.
    NSError *error = nil;
    if (![self.managedObjectContext save:&error])
    {
       // Need code to handle error properly
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }        
}

但由于某种原因,它不是按字母顺序排序,而是按照创建的顺序放置每个项目。我做错了什么?

4 个答案:

答案 0 :(得分:1)

看起来不错。

您是否设置了获取结果控制器以根据displayOrder

进行排序

此外,您应该释放代码中的项目......

答案 1 :(得分:0)

试试这个:

NSMutableArray *items = [NSMutableArray arrayWithArray:fetchedResultsController.fetchedObjects];

或者一步完成(不需要是可变的):

NSArray *items = [fetchedResultsController.fetchedObjects sortedArrayUsingDescriptors:sortDescriptors];

顺便说一句,这似乎是一种排序表的错综复杂的方式。您正在修改数据库中的displayIndex以反映新的排序顺序。据推测,驱动fetchedResultsController的NSFetchRequest正在基于displayIndex进行排序。

它会更简单,不需要更改数据库只需更改fetchRequest并重新配置fetchedResultsController。

来自NSFetchedResultsController docs:

  

修改获取请求

     

你做不到   只需将获取请求更改为   修改结果。如果你想   更改获取请求,您必须:

     

如果您使用缓存,请将其删除   (使用deleteCacheWithName :)。   通常,您不应使用缓存   如果您要更改提取请求。

     

更改提取请求。调用   performFetch:

答案 2 :(得分:0)

似乎你没有用排序的数组刷新tableview。我在我的一个项目中使用以下方法根据状态和名称对联系人数组进行排序:

- (void)refresh {
    if ([NSThread isMainThread]) {
        NSSortDescriptor *descriptorStatus = [[[NSSortDescriptor alloc] initWithKey:@"status" ascending:NO selector:@selector(statusCompare:)] autorelease];
        NSSortDescriptor *descriptorName = [[[NSSortDescriptor alloc] initWithKey:@"displayName" ascending:YES] autorelease]; 
        [contactArray sortUsingDescriptors:[NSArray arrayWithObjects:descriptorStatus, descriptorName, nil]];

        [tableView reloadData];
    } else {
        [self performSelectorOnMainThread:@selector(refresh) withObject:nil waitUntilDone:NO];
    }
}

对于您的项目,您可能不必检查是否在mainthread上执行了刷新,除非从主线程以外的任何线程检索数据。

答案 3 :(得分:0)

为什么不在获取对象时设置排序描述符。