自定义选择器NSSortDescriptor和NSFetchedResultsController [英] Custom Selector For NSSortDescriptor and NSFetchedResultsController

查看:131
本文介绍了自定义选择器NSSortDescriptor和NSFetchedResultsController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一些麻烦,我想知道是否有人可以提供一些指导。

I am running into a bit of trouble and I was wondering if someone could provide some guidance.

我试图创建节标题,顺序如下: 推,繁忙,完成,已取消]。

I am attempting to create section headers with the following order: ["Push", "Busy", "Finished", "Canceled"].

不幸的是,这个订单不能用简单的 。我必须添加一个自定义比较选择器...这样的..:

Unfortunately, this order cannot be realized with a simple "ascending YES/NO" ... I have to add a custom compare selector ... something like this ..:

**其中states映射到[Push,Busy Finished,Canceled]

**Where "states" maps to ["Push", "Busy", "Finished", "Canceled"]

NSSortDescriptor *sortStates = [NSSortDescriptor sortDescriptorWithKey:@"states"
                                                           ascending:NO 
                                                            selector:@selector(compareCustom:)];

因此,我实现了一个compareCustom...但是,自定义排序器如下异常结果:

Therefore, I implemented a "compareCustom" ... however, it turns out that I cannot implement a custom sorter as the following exception results:

***由于未捕获异常NSInvalidArgumentException终止应用程序,原因:'不支持NSSortDescriptor选择器:compareCustom:'

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: compareCustom:'

作为参考,sortDate由以下方式实现:

For reference, the sortDate is implemented by :

request.sortDescriptors = @[sortStates]
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                    managedObjectContext:context
                                                                    sectionNameKeyPath:@"states"
                                                                               cacheName:nil];

所以看起来我不能实现返回NSComparisonResult的compareCustom?我觉得应该是可能的..但我不能弄清楚如何。如果有人可以提供一些建议,我会非常感谢它!

So it looks like I cannot implement a compareCustom which returns a NSComparisonResult? I feel like it should be possible.. but I am unable to figure out how. If someone can provide some advice I would really appreciate it!

还有参考,这里是我的compareCustom方法

Also for reference, here is my "compareCustom" method

-(NSComparisonResult)compareCustom:(NSString *)anotherState {
if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Push"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedSame;
}

else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedAscending;
}
else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedSame;
}
else if ([(NSString *)self isEqualToString:@"Finished"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedAscending;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Finished"]) {
    return NSOrderedDescending;
}
else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Canceled"]) {
    return NSOrderedDescending;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Busy"]) {
    return NSOrderedSame;
}

else if ([(NSString *)self isEqualToString:@"Busy"] && [anotherState isEqualToString:@"Push"]) {
    return NSOrderedAscending;
}

else {
    return NSOrderedSame;
}
}


推荐答案

文档自定义排序不能与SQLite持久存储一起使用:

According to the documentation custom sort doesn't work with SQLite persistent store:


另一方面,SQL存储,编译谓词并将
描述符排序到SQL,并在数据库本身中计算结果。
这主要是为了性能,但这意味着评估
发生在非Cocoa环境中,所以依赖Cocoa的排序描述符(或
谓词)不能工作。支持的排序
选择器是compare:和caseInsensitiveCompare :, localizedCompare :,
localizedCaseInsensitiveCompare :,和localizedStandardCompare:(
后面是Finder的排序,大多数人应该使用大多数
的时间)。此外,你不能使用
SQLite存储来对临时属性进行排序。

The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work. The supported sort selectors are compare: and caseInsensitiveCompare:, localizedCompare:, localizedCaseInsensitiveCompare:, and localizedStandardCompare: (the latter is Finder-like sorting, and what most people should use most of the time). In addition you cannot sort on transient properties using the SQLite store.

所以看来你不能简单地强制 NSFetchedResultsController 以字母顺序显示节。

So it seems you can't simply force NSFetchedResultsController to display sections in other than alphabetical order.

但您可以使用解决方法。向您的实体添加整数类型的附加的持久属性(让我们称之为 sectionOrder )。根据 states 属性设置其值(因此为Push时为0,<$ c为1 $ c>Busy等)。例如,您可以在 awakeFromInsert 方法中执行。

But you can use a workaround. Add additional, persistent attribute of integer type to your entity (let's call it sectionOrder). Set its value according to the states property (so it will be 0 for "Push", 1 for "Busy" etc.) You can do that in awakeFromInsert method, for example.

然后使用 @sectionOrder同时作为 sectionNameKeyPath 和排序描述符中的关键字。您可以使用此 UITableViewDataSource 方法将部分标题设置为推送,繁忙等:

Then use @"sectionOrder" as both sectionNameKeyPath and the keypath in sort descriptor. You can set section titles to be "Push", "Busy" etc. using this UITableViewDataSource method:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [sectionInfo.objects.firstObject name];
}

注册此出色的答案

这篇关于自定义选择器NSSortDescriptor和NSFetchedResultsController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆