views:

123

answers:

3

Hello to everyone,

I cannot understanding why values assign to array objects become "disordered" after executing executeFetchRequest. Well, I'm not certain that fetching is the problem here. Here's the code.

objects=[NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",nil];

NSManagedObject *DB = nil;

for (int i=0;i<[objects count];i++){

DB = [NSEntityDescription      
    insertNewObjectForEntityForName:@"dbTable" 
    inManagedObjectContext:context];

[DB setValue:[objects objectAtIndex:i] forKey:@"item"];
[DB setValue:[NSString stringWithFormat:@"%3.2f", 0] forKey:@"value"];    
}

objects = [context executeFetchRequest:request error:&error];

Printings

new wrong ordering after fetch execution into array objects
index 0 :: Item: d
index 1 :: Item: c
index 2 :: Item: e
index 3 :: Item: b
index 4 :: Item: a

thank you.

A: 

When you execute a fetch request without specifying that you want your items sorted by a specific key, you get a result array which is not ordered. You can extend your fetch request with a sort descriptor using a code snippet such as the following one.

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"value" ascending:YES selector:@selector(caseInsensitiveCompare:)];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];
    [sortDescriptor release];
    [sortDescriptors release];
unforgiven
Hi,I think I misled you guys by putting alphabet ordered values, it was just to demonstrate after fetching results. What my problem really is, is that I want to keep user entering order, without additional attributes in DB. Thank you unforgiven.
BigJoke
+1  A: 

Apply an NSSortDescriptor to your fetch request, e.g.:

NSSortDescriptor *itemDescriptor = [[NSSortDescriptor alloc] initWithKey:@"item" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:itemDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[itemDescriptor release];

will sort on the item name. You could use value, instead.

Alex Reynolds
Hi Alex,I came across that idea too (although not knowing how to do it in obj-c). Now I know how. But what I'm after is to leave the items in the exact order they are entered by a user, and that without using one more attribute in my DB receiving entering order. Is that possible? Thank you for your help.
BigJoke
Unless the user enters the items in an order that can be used as a natural sort (i.e. the value being entered can be sorted on, as-is) I'm fairly sure you would need to use another key that stores the entry ordering, and then sort on that for the fetch.
Alex Reynolds
I get the sense that, behind the scenes, managed object subclasses are thrown into bags of type `NSSet`. Members of a set have no particular order, because the only requirement for constructing a set is that members are unique. The fetch is what applies an ordering on what is read out of the set, assuming a sort descriptor is added to the fetch.
Alex Reynolds
+2  A: 

Due to the underlying database architecture, Core Data stores all objects and to-many references in an unordered fashion. The order you get back from a fetch request is not guaranteed, unless you apply an NSSortDescriptor, as Alex describes. This thread in the Cocoa mailing list details the issues involved, as well as some potential solutions.

These solutions include having an index property that you sort on when performing a fetch request, or implementing a linked list of managed objects and traversing that in order. Brian Webster has created a subclass of NSManagedObject that lets you maintain ordered to-many relationships in your Core Data objects, for which the source code can be found here.

Brad Larson
Interesting answer. Thanks.
Alex Reynolds
Hi Brad, yours and Alex's comments are very enlightening. Brian Webster subclassing is for to-many relationships, not my case. I think the idea for me is another attribute recording user entering order.. yeah, not a sophisticated one but proves working. Thank you.
BigJoke