3

我想构建一个基于数组内容的 NSPredicate 或 NSSortDescriptor(核心数据搜索)。

该数组将按userId:s正确的顺序组成:

[1, 2, 5, 3];

我想以相同的顺序呈现我的 NSFetchedResultsController 的结果。

所以我会:

  1. 获得合适的用户(我已经这样做了)
  2. 使用 s 根据我的排序数组对用户列表进行排序userId

这可能吗,我该怎么做?

4

2 回答 2

3

我认为这是不可能的。对获取请求的结果(对于基于 SQLite 的存储)进行排序是在 SQLite 级别上完成的,并且只能使用存储在数据库中的持久属性。排序描述符不能使用 Objective-C 函数或变量。

所以要么

  • 您向您的实体添加一个额外的属性来描述预期的顺序(如果可能的话),或者
  • 您在获取结果后根据需要对结果进行排序(这意味着您不能再使用获取的结果控制器进行自动更改跟踪)。也许您可以使用此处描述的方法:https ://stackoverflow.com/a/15618277/1187415 。
于 2013-03-31T14:03:15.947 回答
0

上面的答案并不完全正确。你可以做你想做的,但它有点复杂。

  1. 在 NSNumber 上创建一个类别(userID 是一个数字,对吗?)
  2. 使用 objc_setAssoc 将 NSArray 类型的 + 全局变量放到类别中...。

    @interface NSNumber(MyExtension)
    
    + (NSArray *) orderingArray;
    + (void) setOrderingArray: (NSArray *)array;
    
    - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber;
    
    @end
    
    int keyVar = 0;
    
    @implementation NSNumber(MyExtension)
    
    + (NSArray *) orderingArray
    {
     return objc_getAssociatedObject(self, &keyVal);
    }
    + (void) setOrderingArray: (NSArray *)array
    {
        objc_setAssociatedObject(self, &keyVal, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSComparisonResult) myOwnCompareMethodUsingArray:(NSNumber *)theOtherNumber;
    {
     NSArray *a = [self.class orderingArray];
     if(!a) return NSOrderedSame;
     return [@([a indexOfObject:self]) compare: @([a indexOfObject:theOtherNumber])];
    } 
    
  3. 在某处设置数组:

    [NSNumber setOrderingArray:myArrayWithKeys]; 
    
  4. 使用类型的排序描述符:

    [NSSortDescriptor sortDescriptorWithKey:@"userId" ascending:YES selector @selector(myOwnCompareMethodUsingArray:)]
    

这显然适用于具有localizedCaseInsensitiveCompare 的字符串:但是,如果它足够大并覆盖任何fetchLimit/fetchOffset 优化,它将降低查询的性能。请记住,您正在操作的领域必须是独一无二的,否则一切都会陷入困境。

于 2014-10-09T09:13:12.207 回答