2009-07-01 279 views
19

Core Data Documentation指出:如何排序核心數據取出的屬性

取指與[取]屬性關聯可以具有排序順序請求,因此所獲取的屬性可被排序。

如何在Xcode的數據模型編輯器中指定fetched屬性的排序描述符?我無法在任何地方找到相關的字段。如果這有什麼不同,我正在爲iPhone平臺開發。

如果這不可能通過圖形模型編輯器,我該如何去修改代碼中的fetched屬性的獲取請求,以便它具有排序描述符?

+0

添加標籤iphone – Dan 2009-07-01 23:13:09

回答

5

建模工具似乎沒有辦法在獲取請求上設置排序描述符。

在加載模型之後但在將其與持久性存儲協調器關聯之前,應該有可能[1]找到要控制排序順序的提取屬性描述,並用提取替換它們的提取請求有排序描述符設置的請求。

[1]原則上這應該工作。在實踐中,我還沒有這樣做或測試過它。

+1

這個建模工具沒有這個功能太糟糕了 - 好像它在很大程度上減少了能夠在工具中指定提取請求的效用。 – 2009-07-03 11:42:59

+0

這個問題提供了一個以編程方式創建NSFetchedPropertyDescription並將其添加到NSManagedObjectModel的示例:http://stackoverflow.com/questions/5638364/how-do-i-create-an-nsfetchedpropertydescription-programmatically – 2011-04-14 02:40:25

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

這在上面是正確的。你必須添加NSSortDescriptor,你不能在你的數據模型中指定這個對不起。是的,它很長時間了,但這正是我在覈心數據應用程序中所做的。 – 2009-07-03 03:43:05

+25

以上是正常的提取請求的罰款,但與問題無關,這是關於提取屬性和他們的排序。 – Hunter 2009-11-16 18:06:24

0

不幸的是,排序能力有限。例如,你不能使用一個包含數字的NSString字段,並以數字方式對其進行排序,至少不要使用SQLite後備存儲。只要按字母順序排序字符串,僅以數字等形式存儲值,應用於提取請求的NSSortDescriptor就可以正常工作。

+1

您可以使用NSSortDescriptor的initWithKey:升序:選擇器: – 2009-10-04 16:48:59

35

實際上,您可以抓取模型提取的屬性並將排序描述符添加到它(再次,在代碼中)。我用XCode在AppDelegate中生成的標準方法執行此操作,如果您選擇Core Data中的某個模板:

順便說一下。這會對數據模型中的所有模型上的所有提取的屬性進行排序。你可能會喜歡它並且適應性強,但它是處理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; 
} 
-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 PLZ原諒編碼錯誤,這是從我的頭頂。

5

使用添Shadel最偉大的答案,我每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]; 
    } 
} 
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]]; 
} 

更換EntityManagedObjectSubClassentityNamefetchedPropertyNamesortDescriptorKey喲你自己的東西。