【发布时间】:2010-11-21 00:56:01
【问题描述】:
我有两个模型 Department 和 Worker。部门与工人有一对多的关系(工人)。 工人有名字字段。如何通过访问 departmet.workers 获取按名字排序的工作人员列表?有没有办法在多对关系中添加排序描述符?
【问题讨论】:
-
它是一个旧线程.. 但它有效并帮助了我很多时间!为这个线程添加书签谢谢大家..!!
我有两个模型 Department 和 Worker。部门与工人有一对多的关系(工人)。 工人有名字字段。如何通过访问 departmet.workers 获取按名字排序的工作人员列表?有没有办法在多对关系中添加排序描述符?
【问题讨论】:
Core Data 中的多对多关系被建模为无序集。但是,您可以在包含排序描述符的 Department 实体上创建一个 fetched 属性,或者您可以在应用程序中对内存中的集合进行排序(NSArrayController 将通过设置其 sortDescriptors 属性为您完成此操作。
【讨论】:
您需要定义自己的方法,例如 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];
}
【讨论】:
Hunter 的代码片段几乎对我有用,除了“workers”是一个 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];
}
【讨论】:
对 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];
【讨论】:
[allObjects] 都不是必需的,因为 NSSet 本身实现了 sortedArrayUsingDescriptors:,从而避免了临时 NSArray 的多余创建。
我注意到这已经很老了,但人们仍然会遇到它(我确实遇到过)
Adrian Schö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]]];
}
显然,当您添加大量工人时,这是低效的,但您可以移动 [department orderWorkers];在添加所有工人之后发生。
【讨论】:
比 Adrian Schö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];
}
【讨论】: