xcode 如何对核心数据获取的属性进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1071765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:05:00  来源:igfitidea点击:

How to sort Core Data fetched properties

iphonexcodesortingcore-datafetched-property

提问by Daniel Dickison

The Core Data Documentationstates that:

核心数据文件指出:

The fetch request associated with the [fetched] property can have a sort ordering, and thus the fetched property may be ordered.

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

How do I specify the sort descriptors for the fetched property in Xcode's data model editor? I can't find a relevant field anywhere. I'm developing for the iPhone platform, if this makes any difference.

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

If this is not possible via the graphical model editor, how do I go about modifying the fetch request for the fetched property in code so that it has a sort descriptor?

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

采纳答案by Jim Correia

The modeling tool doesn't appear to have a way to set the sort descriptors on the fetch request.

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

It should be possible[1] to, after loading the model but before associating it with a persistent store coordinator, to find the fetched property descriptions for which you want to control the sort order, and replace their fetch requests with fetch requests that have sort descriptors set on them.

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

[1] In principle this should work. In practice, I have not done so or tested it.

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

回答by Tim Shadel

You can actually grab the model fetched property and add the sort descriptors to it (again, in code). I did this in the standard method that XCode generates in your AppDelegate if you choose one of the templates with Core Data:

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

By the way. This sorts ALL fetched properties on ALL models in your data model. You could get fancy and adaptive with it, but it was the most succinct way to handle sorting the 7 separate models that each had fetched properties that needed to be sorted by name. Works well.

顺便一提。这会对数据模型中所有模型的所有获取的属性进行排序。你可以用它来获得幻想和适应性,但它​​是处理排序 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;
}

回答by mmc

You don't specify them in the graphical editor (as far as I know).

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

You specify them in the code where you make the fetch.

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

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"];

回答by rob5408

Using Tim Shadel's great answer I added per-NSManagedObject subclass sorting...

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

...in Tier.m (which is a NSManagedObject subclass)...

...在 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];
    }
}

回答by leanne

For a single fetched property, Swift 4, Xcode 9.4:

对于单个获取的属性,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

Here's the same thing the loooonnnnnnggggggg way:

这与 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

Note: for this example, I force-unwrapped values. Make sure that you account for optional values in your actual code!

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

回答by Rudolf Adamkovi?

Put this into your NSManagedObjectsubclass:

把它放到你的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]];
}

Replace EntityManagedObjectSubClass, entityName, fetchedPropertyNameand sortDescriptorKeywith your own stuff.

用你自己的东西替换EntityManagedObjectSubClass, entityName,fetchedPropertyNamesortDescriptorKey

回答by Rudolf Adamkovi?

Sadly, though, the ability to sort is somewhat limited. For example, you cannot take a field that is an NSString containing a number, and sort it numerically, at least not with a SQLite backing store. As long as you are sorting alphabetically on strings, numerically only on values stored as numbers and so forth, though, the NSSortDescriptor applied to the fetch request works just fine.

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

回答by PapaSmurf

Jeff, if the strings are right-aligned, you could just sort on the strings; " 123" > " 23" and so on. But iirc ascii space is after the numbers, and if so, then what you would do is create a dynamic property that is an NSNumber (which supports the compare: method), and use the numberFromString: method to make a number from the string. Then you can specify the number field in the sort. In the interface:

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

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

in the implementation:

在实施中:

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

ps plz forgive coding errors, this is off the top of my head.

ps 请原谅编码错误,这是我的头顶。