Tuesday, April 20, 2010

Fetched LIst Controller: Using a predicate on a relationship.

In my previous blog entry I was pretty proud of figuring out the way to select multiple word lists and then build a predicate that found the union of all the words belong to those lists.  It wasn't clear from the documentation and websearches how to do it.   It worked great on the simulator.  However when I put it on the device, it was extremely slow (which is probably why there wasn't great documentation on how to do it).

I ended up just abandoning using a fetched data controller for this information, and just building a complete set that contains all the words I want.  I modified:


JLTableContainer *container=
[JLTableContainer createFetchControlledTable:nil    forEntity:@"WordInformation" forSimpleKey:@"wordName"    inContext: [SightWordState Instance].control.managedObjectContext 
createSectionsBy:nil  controlledBy:nil];
NSArray *selectedLists=[listSelectDialog currentSelectedItems:@"ListName"];
NSPredicate *predicate= [NSPredicate predicateWithFormat:@"ANY containedIn in %@",selectedLists ]; 
[container updatePredicate:predicate];
UISelectionMaster * selector=[[UISelectionMaster alloc] init];
selector.listToSelect=container;
[self.navigationController pushViewController:selector animated:true];
[selector startSelection];
self.wordSelectDialog=selector;
[selector showToolbar:@"Add Words" target:self action:@selector(wordsSelected:)];
To:
- (IBAction) listsSelected:(id) sender
{

NSArray *selectedLists=[listSelectDialog currentSelectedItems:@"ListName"];
NSMutableSet *words=[[NSMutableSet alloc]init];

for (WordList *list in selectedLists)
{
[words unionSet:list.containedWords];
}
JLTableContainer *container=
[JLTableContainer createSetController:nil forList:words sortKey:@"wordName"
inContext:[SightWordState Instance].control.managedObjectContext
controlledBy:nil];
UISelectionMaster * selector=[[UISelectionMaster alloc] init];
selector.listToSelect=container;
[self.navigationController pushViewController:selector animated:true];

[selector startSelection];
self.wordSelectDialog=selector;
[selector showToolbar:@"Add Words" target:self action:@selector(wordsSelected:)];

}
I didn't get timing numbers, but there was a perceptibly strong performance improvement for the second set of code.  This is one of the reasons I'm writing a general library, I can change how something is implemented with (hopefully) minimal impact to the remainder of the code.


No comments:

Post a Comment