views:

55

answers:

1

So I got entities Level and Tile. Level has a to-many relationship with Tile. Tile has a property 'index'.

Right now I'm using this code to get the tiles array of Level sorted:

- (NSArray *)sortedTiles  
{  
    NSMutableArray *sortedTiles = [NSMutableArray arrayWithArray:[self.tiles allObjects]];  
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"index" ascending:YES];  
    [sortedTiles sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];  
    [sortDescriptor release];  
    return sortedTiles;  
}

This works, but I want to be able to retrieve a single Tile with a certain index, so I wrote this method in Level.h:

- (Tile *)tileWithIndex:(NSInteger)index;

The implementation is fairly simple:

- (Tile *)tileWithIndex:(NSInteger)index  
{  
    NSArray *sortedTiles = [self sortedTiles];  
    Tile *tile = [sortedTiles objectAtIndex:index];  
    return tile;  
}

Now, ofcourse this isn't the most efficient way in doing so because the tiles array has to be allocated and sorted each time, so I was thinking: if I just add an instance variable to Level, 'sortedTiles', then I won't have to rebuild it each time. But Level is a subclass of NSManagedObject, so is this possible and/or wise to do?

A: 

I wouldn't. The NSManagedObjects are a reflection of a record in the database and adding additional member variables outside the model strikes me as adding something that doesn't belong.

There are other, better ways to accomplish the same thing. The simplest would be to get the controller or delegate that's fetching all these objects to fetch, sort and retain the array locally.

For large or complex situations, you can use an NSFetchRequestController to collect, sort and dole out NSManagedObjects as needed. This integrates nicely into a UITableViewController. I haven't done any performance testing, but for a situation where there are potentially a large number of records, I would try this first to see if the Fetch Results classes own cache management is sufficient.

John Franklin
I'm not sure I agree that you shouldn't add iVars to an NSManagedObject subclass in general. As long as those iVars aren't intended to persist and their accessors account for the instance's isFault state, there are plenty of valid and good uses. As to the OP's use, I'm not sure I fully understand the question, but I "feel" like it's overkill. :-)
Joshua Nozzi
Can you give an example? I'm struggling to come up with even one that (1) isn't better stored in the controller or delegate managing the app, view or use case, and (2) doesn't cause issues when there are multiple NSManagedObjectContexts each holding a version of the object.
John Franklin
The main advantage of using the instance variable would be the optimization of the `tileWithIndex:` method of Level. Right now, every time I call this method, the sortedTiles has to be rebuilt. If I store the sortedTiles in an instance variable of Level, I can just use that variable every time.
Rits