代码之家  ›  专栏  ›  技术社区  ›  FKDev

使用NSFetchedResultController自定义排序(子类化NSSortDescriptor)

  •  6
  • FKDev  · 技术社区  · 15 年前

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

    here ),我尝试使用NSSortDescriptor派生类来重写compareObject:toObject:message。

    here ).

    我的问题是:如何强制NSFetchedResultscontroller使用compareObject:toObject:message对数据进行排序?(它是否能与大数据集一起工作)

    另一个解决方案是:
    -调用performFetch通过SQL对数据排序(未调用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];
    }
    

    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
    
    1 回复  |  直到 9 年前
        1
  •  7
  •   Marcus S. Zarra    15 年前

    关于你的问题和评论。你需要把这些对象放到内存中进行排序。一旦它们在内存中,您就可以使用一种方便的方法来确定与某个点的距离。

    若要减少拉入内存的对象数,可以计算最大值和最小值,然后对其进行筛选,在排序之前减小搜索半径。

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