FKD*_*Dev 6 iphone core-data nssortdescriptor nsfetchedresultscontroller
我想使用NSFetchedResultsController和NSSortDescriptor提供自定义排序.
作为通过NSSortDescriptor消息进行自定义排序 - (id)initWithKey:ascending:selector:是不可能的(参见此处),我尝试使用NSSortDescriptor派生类来覆盖compareObject:toObject:消息.
我的问题是compareObject:toObject:并不总是被调用.似乎只有当数据已经在内存中时才会调用它.当第一次从商店检索数据时,存在使用基于数据库的排序而不是compareObject:toObject的某种优化.(见这里).
我的问题是:如何强制NSFetchedResultscontroller使用compareObject:toObject:消息对数据进行排序?(并且它适用于大型数据集)
一种解决方案是使用二进制存储而不是sqlite存储,但我不想这样做.
另一种解决方案是:
-call performFetch通过SQL(compareObject未调用)对数据进行排序 - 对数据进行
修改并将其反转.
-call performFetch再次调用(compareObject被调用)
它在我的情况下工作,但它是一个黑客,我不确定它将始终有效(特别是对于大数据集(大于批量大小)).
更新:您可以使用CoreDataBooks示例进行重现.
在RootViewController.m中,添加这个丑陋的黑客:
- (void)viewWillAppear:(BOOL)animated {
Book* book = (Book *)[NSEntityDescription insertNewObjectForEntityForName:@"Book"
inManagedObjectContext:[self fetchedResultsController].managedObjectContext];
[[self fetchedResultsController] performFetch:nil];
[[self fetchedResultsController].managedObjectContext deleteObject:book];
[self.tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)
在RootViewController.m中,将排序描述符代码替换为:
MySortDescriptor *myDescriptor = [[MySortDescriptor alloc] init];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:myDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
Run Code Online (Sandbox Code Playgroud)
添加MySortDescriptor类:
@implementation MySortDescriptor
-(id)init
{
if (self = [super initWithKey:@"title" ascending:YES selector:@selector(compare:)])
{
}
return self;
}
- (NSComparisonResult)compareObject:(id)object1 toObject:(id)object2
{
//set a breakpoint here
return [[object1 valueForKey:@"author" ] localizedCaseInsensitiveCompare:[object2 valueForKey:@"author" ] ];
}
//various overrides inspired by [this blog post][3]
- (id)copy
{
return [self copyWithZone:nil ];
}
- (id)mutableCopy
{
return [self copyWithZone:nil ];
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return [self copyWithZone:zone ];
}
- (id)copyWithZone:(NSZone*)zone
{
return [[MySortDescriptor alloc] initWithKey:[self key] ascending:[self ascending] selector:[self selector]];
}
- (id)reversedSortDescriptor
{
return [[[MySortDescriptor alloc] initWithKey:[self key] ascending:![self ascending] selector:[self selector]] autorelease];
}
@end
Run Code Online (Sandbox Code Playgroud)
参考你的问题和评论.您将需要将对象拉入内存以对其进行排序.一旦它们在内存中,您可以使用便捷方法来确定距离点的距离.
要减少您拉入内存的对象数量,您可以计算最大值和最小值,然后对其进行过滤,在排序之前减少搜索的半径.
除非它在内存中,否则无法对计算值进行排序.
| 归档时间: |
|
| 查看次数: |
3005 次 |
| 最近记录: |