我有两个模特部门和工人。部门与工人有很多关系(工人)。 Worker具有firstName字段。如何通过访问departmet.workers获得按firstName排序的工作人员列表?有没有办法在多对多关系中添加排序描述符?
答案 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]]];
}
显然,当你添加大量的工人时,这是低效的,但你可以移动[部门订单工人];在所有工人加入之后发生。