gpt4 book ai didi

iphone - 使用 NSFetchedResultController 进行自定义排序(子类化 NSSortDescriptor)

转载 作者:行者123 更新时间:2023-12-03 18:39:19 27 4
gpt4 key购买 nike

我想使用 NSFetchedResultsController 和 NSSortDescriptor 提供自定义排序。

由于无法通过 NSSortDescriptor 消息 -(id)initWithKey:ascending:selector: 进行自定义排序(请参阅 here ),因此我尝试使用 NSSortDescriptor 派生类来覆盖compareObject:toObject: 消息。

我的问题是,compareObject:toObject: 并不总是被调用。似乎只有当数据已经在内存中时才会调用它。当第一次从存储中检索数据时,有某种优化使用基于数据库的排序而不是compareObject:toObject。 (参见here)。

我的问题是:如何强制 NSFetchedResultscontroller 使用compareObject:toObject: 消息对数据进行排序? (以及它是否适用于大数据集)

一种解决方案是使用二进制存储而不是 sqlite 存储,但我不想这样做。

另一个解决方案是:
-调用performFetch通过SQL对数据进行排序(不调用compareObject)
-对数据进行修改并反转。
-再次调用performFetch(调用compareObject)
它在我的情况下确实有效,但它是一个黑客,我不确定它是否总是有效(特别是对于大数据集(大于批量大小))。

更新:您可以使用 CoreDataBooks 示例进行重现。
在 RootViewController.m 中,添加这个丑陋的 hack:

- (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];
}

在 RootViewController.m 中,将排序描述符代码替换为:

MySortDescriptor *myDescriptor = [[MySortDescriptor alloc] init];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:myDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

添加 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

最佳答案

引用您的问题和评论。您需要将对象拉入内存中以对它们进行排序。一旦它们被存储在内存中,您就可以使用一种方便的方法来确定距某个点的距离。

要减少拉入内存的对象数量,您可以计算最大值和最小值,然后对这些值进行过滤,从而在排序之前减小搜索半径。

除非计算值在内存中,否则无法对其进行排序。

关于iphone - 使用 NSFetchedResultController 进行自定义排序(子类化 NSSortDescriptor),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4106184/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com