22

核心数据文档指出:

与 [fetched] 属性关联的获取请求可以具有排序顺序,因此可以对获取的属性进行排序。

如何在 Xcode 的数据模型编辑器中为 fetched 属性指定排序描述符?我在任何地方都找不到相关领域。我正在为 iPhone 平台开发,如果这有什么不同的话。

如果通过图形模型编辑器无法做到这一点,我该如何修改代码中 fetched 属性的 fetch 请求,使其具有排序描述符?

4

8 回答 8

37

您实际上可以获取模型获取的属性并将排序描述符添加到它(再次,在代码中)。如果您选择具有核心数据的模板之一,我会在 XCode 在您的 AppDelegate 中生成的标准方法中执行此操作:

顺便一提。这会对数据模型中所有模型的所有获取的属性进行排序。你可以对它进行幻想和适应,但它是处理对 7 个单独模型进行排序的最简洁的方法,每个模型都获取了需要按名称排序的属性。效果很好。

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    

    // Find the fetched properties, and make them sorted...
    for (NSEntityDescription *entity in [managedObjectModel entities]) {
        for (NSPropertyDescription *property in [entity properties]) {
            if ([property isKindOfClass:[NSFetchedPropertyDescription class]]) {
                NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
                NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];

                // Only sort by name if the destination entity actually has a "name" field
                if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"name"]) {
                    NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
                    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
                    [sortByName release];
                }
            }
        }
    }

    return managedObjectModel;
}
于 2009-09-26T05:19:05.357 回答
13

您没有在图形编辑器中指定它们(据我所知)。

您在进行提取的代码中指定它们。

NSFetchRequest* request = [[NSFetchRequest alloc] init];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"whatYouAreLookingFor"
    inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];

// here's where you specify the sort
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc]
                                initWithKey:@"name" ascending:YES];
NSArray* sortDescriptors = [[[NSArray alloc] initWithObjects: sortDescriptor, nil] autorelease];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];

fetchedResultsController = [[NSFetchedResultsController alloc]
               initWithFetchRequest:request
               managedObjectContext:self.managedObjectContext
                 sectionNameKeyPath:nil
                          cacheName:@"myCache"];
于 2009-07-02T22:31:11.847 回答
5

建模工具似乎没有办法在获取请求上设置排序描述符。

应该有可能[1] 在加载模型之后但在将其与持久存储协调器关联之前,找到要控制其排序顺序的提取属性描述,并将其提取请求替换为具有排序的提取请求在它们上设置的描述符。

[1] 原则上这应该有效。在实践中,我没有这样做或测试过。

于 2009-07-02T22:22:35.313 回答
5

使用 Tim Shadel 的出色答案,我添加了 per-NSManagedObject 子类排序...

...在 Tier.m 中(这是一个 NSManagedObject 子类)...

+ (void)initialize
{
    if(self == [Tier class])
    {
        NSFetchedPropertyDescription *displayLessonPropertyDescription = [[[Tier entityDescription] propertiesByName] objectForKey:@"displayLesson"];
        NSFetchRequest *fetchRequest = [displayLessonPropertyDescription fetchRequest];

        NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"displayOrder" ascending:YES];
       [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
        [sortByName release];
    }
}
于 2012-11-04T01:22:27.990 回答
1

对于单个获取的属性,Swift 4,Xcode 9.4:

// retrieve the fetched property's fetch request    
let fetchedPropertyRequest = (modelName.entitiesByName["entityName"]!.propertiesByName["fetchedPropertyName"] as! NSFetchedPropertyDescription).fetchRequest

// set up the sort descriptors
let sortDescriptors = [NSSortDescriptor(key: "keyName", ascending: true)]

// add the sort descriptors to the fetch request
fetchedPropertyRequest!.sortDescriptors = sortDescriptors

这是 loooonnnnnnggggggg 的方式:

// retrieve the fetched property's fetch request
let theEntityDescription: NSEntityDescription = modelName.entitiesByName["entityName"]!
let theFetchedPropertyDescription = theEntityDescription.propertiesByName["fetchedPropertyName"]! as! NSFetchedPropertyDescription
let theFetchedPropertyRequest = theFetchedPropertyDescription.fetchRequest

// set up the sort descriptors
let sortDescriptor1 = NSSortDescriptor(key: "keyName", ascending: true)
let theSortDescriptors = [sortDescriptor1]

// add the sort descriptors to the fetch request
theFetchedPropertyRequest!.sortDescriptors = theSortDescriptors

注意:对于这个例子,我强制展开值。确保在实际代码中考虑了可选值!

于 2018-06-30T23:33:05.447 回答
0

可悲的是,排序的能力有些有限。例如,您不能获取一个包含数字的 NSString 字段,并对其进行数字排序,至少不能使用 SQLite 后备存储。但是,只要您按字母顺序对字符串进行排序,仅对存储为数字的值进行数字排序等等,应用于获取请求的 NSSortDescriptor 就可以正常工作。

于 2009-09-06T16:13:15.807 回答
0

把它放到你的NSManagedObject子类中:

+ (void)initialize
{
    if (self != [EntityManagedObjectSubClass class]) return;
    NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    NSEntityDescription *entityDescription = [managedObjectModel entitiesByName][@"entityName"];
    NSFetchedPropertyDescription *fetchedPropertyDescription = [entityDescription propertiesByName][@"fetchedPropertyName"];
    NSFetchRequest *fetchRequest = [fetchedPropertyDescription fetchRequest];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sortDescriptorKey" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
}

用你自己的东西替换EntityManagedObjectSubClass, entityName,fetchedPropertyName和。sortDescriptorKey

于 2013-01-23T13:01:35.023 回答
-1

杰夫,如果字符串是右对齐的,你可以对字符串进行排序;“123”>“23”等等。但是 iirc ascii 空格在数字之后,如果是这样,那么您要做的就是创建一个动态属性,它是一个 NSNumber(它支持 compare: 方法),并使用 numberFromString: 方法从字符串中生成一个数字。然后您可以在排序中指定数字字段。在界面中:

@property NSString *stringIsaNumber; // in the data model
@property NSNumber *number;

在实施中:

@dynamic stringIsaNumber; 
- (NSNumber *) number ;
{ return [self.stringIsaNumber numberFromString]; }
- (void) setNumber:(NSNumber *)value;
{ self.stringIsaNumber = [NSString stringWithFormat:@"%5i",value) }

ps 请原谅编码错误,这是我的想法。

于 2011-02-16T00:06:39.573 回答