核心数据表视图部分使用NSSortDescriptor按工作日排序

时间:2010-01-30 14:17:19

标签: iphone core-data nsfetchedresultscontroller nssortdescriptor

我目前正在尝试将我的对象数组按天订单排序,以便按正确的顺序对其进行分组,即星期一,星期二,星期三,然后是开始时间。

唯一的问题是我无法弄清楚如何做到这一点,我的代码目前看起来像这样:按字母顺序排序,然后按时间排序:

NSString *sectionKey = nil;
switch (tab) {

case kByWeekA: {
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:NO];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"starttime" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];
sectionKey = @"day";
break;
}
case kByWeekB:{
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:YES];
NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"starttime" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1, sortDescriptor2, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor1 release];
[sortDescriptor2 release];
[sortDescriptors release];
sectionKey = @"day";
break;
}
default:
break;
}

请帮忙!

2 个答案:

答案 0 :(得分:13)

我看到两个解决方案:

  1. 为您的排序描述符创建自定义比较,查看“day”键并根据需要对其进行排序。请参阅指定自定义比较here
  2. 将“day”键设为整数,并按所需顺序使用枚举值。
  3. 更新2 选项2的示例代码:

    - 将“day”属性更改为数字(Int16)并添加瞬态(非持久性)“dayName”字符串属性。

    - 添加工作日的枚举:

    typdef enum {
        kMonday,
        kTuesday,
        kWednesday,
        kThursday,
        kFriday,
        kSaturday,
        kSunday
    } WeekDay;
    

    - 将托管对象的“day”属性设置为NSNumber对象。例如:

    object.day = [NSNumber numberWithInteger:kMonday];
    

    - 为瞬态“dayName”属性实现getter函数:

    - (NSString*)dayName {
        switch ((WeekDay)self.day.integerValue) {
            case kMonday:
                return @"Monday";
                break;
            case kTuesday:
                return @"Tuesday";
                break;
            case kWednesday:
                return @"Wednesday";
                break;
            case kMonday:
                return @"Monday";
                break;
            case kThursday:
                return @"Thursday";
                break;
            case kFriday:
                return @"Friday";
                break;
            case kSaturday:
                return @"Saturday";
                break;
            case kSunday:
                return @"Sunday";
                break;
        }
    }
    

    - 在获取请求中,按“day”排序并使用“dayName”作为节名称键路径。

    <强>更新
    注意:选项1适用于排序数组,但Core Data为'不支持的NSSortDescriptor选择器抛出'NSInvalidArgumentException'异常:weekdayCompare:'

    选项1的示例代码:

    // category on NSString for custom comparison
    @interface NSString (WeekdayComparison)
    - (NSComparisonResult)weekdayCompare:(NSString*)otherDay;
    @end
    @implementation NSString (WeekdayComparison)
    - (NSComparisonResult)weekdayCompare:(NSString*)otherDay {
        NSArray *weekDays = [NSArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday", nil];
    
        NSUInteger selfIndex = [weekDays indexOfObject:self];
        NSUInteger otherDayIndex = [weekDays indexOfObject:otherDay];
    
        if (selfIndex < otherDayIndex) {
            return NSOrderedAscending;
        }
        else if (selfIndex > otherDayIndex) {
            return NSOrderedDescending;
        } else {
            return NSOrderedSame;
        }
    }
    @end
    

    使用新的比较方法:

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"day" ascending:YES selector:@selector(weekdayCompare:)];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
    [sortDescriptor release];
    

答案 1 :(得分:0)

我正在按照相同的要求对部分进行自定义排序,解决方案#1非常适合我,谢谢!

我想补充的一点是,在加载瞬态属性后如果你的应用程序在加载后几秒钟内神秘崩溃,你需要重置数据库。

NSError *error;
NSURL *applicationDocumentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *databaseURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"My Database Name"];
[[NSFileManager defaultManager] removeItemAtPath:databaseURL.path error:&error];

希望这有帮助!