排序到多个关系在核心数据中设置

时间:2009-08-19 17:03:38

标签: iphone core-data

我有两个模特部门和工人。部门与工人有很多关系(工人)。 Worker具有firstName字段。如何通过访问departmet.workers获得按firstName排序的工作人员列表?有没有办法在多对多关系中添加排序描述符?

6 个答案:

答案 0 :(得分:31)

Adrian Hosey的代码略有改进:

而不是手动迭代所有工人,你也可以这样做:

-(NSArray *)sortedWorkers {
  NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
  NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

  return [self.workers sortedArrayUsingDescriptors:sortDescriptors];
}

可能与内部的迭代完全相同,但也许它们以某种方式使它更有效。这肯定少打字......

注意:以上仅适用于iOS 4.0+和OSX 10.6+。在旧版本中,您需要将最后一行替换为:

  return [[self.workers allObjects] sortedArrayUsingDescriptors:sortDescriptors];

答案 1 :(得分:7)

核心数据中的多对多关系被建模为无序集。但是,您可以在包含排序描述符的Department实体上创建fetched属性,或者可以在应用程序内对内存进行排序(NSArrayController将通过设置其sortDescriptors属性来为您执行此操作)。

答案 2 :(得分:7)

AdrianSchönig解决方案的小改进:

现在有必要将self.workers转换为NSSet *

-(NSArray *)sortedWorkers {
   NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
   NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

   return [(NSSet*)self.workers sortedArrayUsingDescriptors:sortDescriptors];
 }

答案 3 :(得分:3)

Hunter的代码片段几乎对我有用,除非“worker”是NSSet,我必须首先将它加载到NSMutableArray中:

- (NSArray *)sortedWorkers {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

    NSMutableArray *sortThese = [NSMutableArray arrayWithCapacity:[self.workers count]];
    for (id worker in self.workers) {
        [sortThese addObject:worker];
    }

    return [sortThese sortedArrayUsingDescriptors:sortDescriptors];
}

答案 4 :(得分:2)

您需要定义自己的方法,例如sortedWorkers。像这样:

- (NSArray *)sortedWorkers {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortNameDescriptor, nil] autorelease];

    return [self.workers sortedArrayUsingDescriptors:sortDescriptors];
}

答案 5 :(得分:1)

我注意到这已经很老了,但人们仍然会遇到它(我做过)

AdrianSchönig的帖子很好。我发现它对基础知识很有用,但每次要访问工作集时都必须这样做。这是非常低效的!

相反,更好的方法是每次插入新对象时进行排序,然后将其保存为CoreData中的Set。这意味着每次调用CoreData时,都会订购工作人员。

我使用NSManagedObject的类别(Worker + Methods.h)为我的系统做了这个。在这里,我有一个新的Worker

的init方法
// Worker+Methods.m
+(Worker *)newWorkerWithFirstname:(NSString *)firstName department:(Department *)department managedContext:(NSManagedObjectContext *)context {
    Worker *w = [NSEntityDescription insertNewObjectForEntityForName:@"Worker" inManagedObjectContext:context];
    w.firstName = firstName;
    w.department = department;

    [department orderWorkers];
    return s;
}


//Department+Methods.m
-(void)orderServices {
    NSSortDescriptor *sortNameDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES] autorelease];
    self.workers = [[NSSet alloc] initWithArray:[self.workers sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortNameDescriptor]]];
}

显然,当你添加大量的工人时,这是低效的,但你可以移动[部门订单工人];在所有工人加入之后发生。