3

我有一个Tag带有字符串属性的实体tagName。我去获取这个实体中的所有对象到一个NSFetchedResultsController,但我希望带有tagName“Main”的标签成为第一个对象。这就是我现在正在做的事情:

 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext];

[fetchRequest setEntity:entity];

NSSortDescriptor *lastDescriptor2 =
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:NO comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) {
    NSLog(@"compare");
    if ([tag1 isEqualToString:@"main"]) return NSOrderedAscending;
    if ([tag2 isEqualToString:@"main"]) return NSOrderedDescending;
    return [tag1 compare:tag2];
}] autorelease];  

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor2]];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
self.fetchedResultsController.delegate=self;   

if (![[self fetchedResultsController] performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}

这段代码在我的viewDidLoad方法中被调用,并且只被调用一次。第一次调用它时,由于某种原因,这里的 sortDescriptor 不适用——它只是没有被调用(NSLog语句也没有出现)。我的结果仅根据BOOL我指定的值返回ascending- 该块被忽略。

但是当我将一个新Tag对象插入到MOCNSFetchedResultsController调用更新委托方法时,实际的 sortDescriptor 被应用,并且NSLog(@"compare")finally 出现,但只有当我对对象进行更新时!无论我尝试了什么,我都无法将排序应用于初始提取。

有什么想法吗?

4

1 回答 1

1

正如您可能已经看到的那样,如果您传递给 NSFetchRequest 的谓词是块谓词,那么您的获取请求将失败。发生这种情况是因为 CoreData 需要将您的谓词转换为 SQL,以便它可以针对数据库运行它。结果是谓词永远不会与获取请求产生的对象进行实际比较。

排序描述符也是如此。执行获取时,获取请求不执行与对象的比较。它作为 SQL 的一部分传递。

您还描述了我上面描述的规则的一个有趣的例外。当你有一个现有的 NSFetchedResultsController 并将一个对象添加到 NSManagedObjectContext 时,NSFetchedResultsController 会通过针对对象评估 NSPredicate 和 NSSortDescriptor 来更新,而不是将它们转换为 SQL。

于 2013-10-20T05:39:49.423 回答