I am doing this is soon as the app starts, luckily I have to do it only once in a singleton class called CMIDataManager, my app is taking too long to launch.
The plist contains:
Commanders.plist:
German - Array
Soviet - Array
each commander array has 19 commander and each commander has 5 abilities (mapping through a unique ability uid).
Abilities.plist:
GermanAbilities - Array
SovietAbilities - Array
Each array contains 40 abilities with a uid (used for mapping commanders to abilities)
At the start, I need to make a model class, so I iterate commander's abilities uid against each Ability hid, once a match is found I add the ability model object to Commaders model object.
How can I do it faster? Would using block based enumeration speed it up? How can I use it?
-(void)loadCommandersAndAbilities{
#pragma German Abilities iteration
NSString* abilitiesPlistPath = [[NSBundle mainBundle] pathForResource:@"Abilities" ofType:@"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:abilitiesPlistPath];
NSArray *tempArray = [dictionary objectForKey:@"GermanAbilities"];
NSArray *tempArray2 = [dictionary objectForKey:@"SovietAbilities"];
NSMutableArray *tempAbilitiesArray = [[NSMutableArray alloc] initWithCapacity:tempArray.count];
for (NSDictionary *dict in tempArray) {
Ability *ability = [[Ability alloc] init];
[ability populateWithDictionary:dict];
[tempAbilitiesArray addObject:ability];
NSLog(@"Adding object %@ to temp abilities",ability.name);
}
self.germanAbilitiesArray = [NSArray arrayWithArray:tempAbilitiesArray];
[tempAbilitiesArray removeAllObjects];
#pragma Soviet abilities iteration
for (NSDictionary *dict in tempArray2) {
Ability *ability = [[Ability alloc] init];
[ability populateWithDictionary:dict];
[tempAbilitiesArray addObject:ability];
}
self.sovietAbilitiesArray = [NSArray arrayWithArray:tempAbilitiesArray];
#pragma German commander itertation
NSString* commandersPlistPath = [[NSBundle mainBundle] pathForResource:@"Commanders" ofType:@"plist"];
dictionary = [[NSDictionary alloc] initWithContentsOfFile:commandersPlistPath];
tempArray = [dictionary objectForKey:@"German"];
tempArray2 = [dictionary objectForKey:@"Soviet"];
NSLog(@"Temp German commadner array is %@", tempArray);
NSLog(@"Temp Soviet commadner array is %@", tempArray2);
NSMutableArray *tempCommandersArray = [[NSMutableArray alloc] initWithCapacity:tempArray.count];
NSMutableArray *tempCommandersArray2 = [[NSMutableArray alloc] initWithCapacity:tempArray2.count];
for (NSDictionary *dict in tempArray) {
Commander *commander = [[Commander alloc] init];
[commander populateWithDictionary:dict];
for (NSNumber *uid in commander.abilitiesUIDArray) {
NSLog(@"uid %@", uid);
for (Ability *ability in self.germanAbilitiesArray) {
NSLog(@"ability uid is : %@, target uid %@ ",ability.uid, uid);
if ([ability.uid isEqualToNumber: uid]) {
NSLog(@"Adding abilty %@ to commander %@: ",ability.name, commander.name);
[commander.abilitiesArray addObject:ability];
NSLog(@"Current commander abilty array is %@: ",commander.abilitiesArray);
}
}
}
[tempCommandersArray addObject:commander];
}
self.germanCommandersArray = [NSArray arrayWithArray:tempCommandersArray];
NSLog(@"Final german Commaders %@",self.germanCommandersArray);
#pragma Soviet commander itertation
for (NSDictionary *dict in tempArray2) {
Commander *commander = [[Commander alloc] init];
[commander populateWithDictionary:dict];
for (NSNumber *uid in commander.abilitiesUIDArray) {
NSLog(@"uid %@", uid);
for (Ability *ability in self.sovietAbilitiesArray) {
NSLog(@"ability uid is : %@, target uid %@ ",ability.uid, uid);
if ([ability.uid isEqualToNumber: uid]) {
NSLog(@"Adding abilty %@ to commander %@: ",ability.name, commander.name);
[commander.abilitiesArray addObject:ability];
NSLog(@"Current commander abilty array is %@: ",commander.abilitiesArray);
}
}
}
[tempCommandersArray2 addObject:commander];
}
self.sovietCommandersArray = [NSArray arrayWithArray:tempCommandersArray2];
NSLog(@"Final Soviet Commaders %@",self.germanCommandersArray);
}
Adding images:
seems like the issues was in this loop:
if ([ability.uid isEqualToNumber: uid]) {
[commander.abilitiesArray addObject:ability];
}
once i have find a match for commander's ability in the list of all abilities, I don't need to check for that ability to match with rest of the abilities, so I added a break statement.
if ([ability.uid isEqualToNumber: uid]) {
//NSLog(@"Adding abilty %@ to commander %@: ",ability.name, commander.name);
[commander.abilitiesArray addObject:ability];
//NSLog(@"Current commander abilty array is %@: ",commander.abilitiesArray);
break;
}
I also added this to the code to make it run on background thread, bringing the launch time down from 6 s to .5 second.
-(instancetype)init {
self = [super init];
if(self) {
[self performSelectorInBackground:@selector(loadCommandersAndAbilities) withObject:nil];
//[self loadCommandersAndAbilities];
// NSOperationQueue
}
return self;
}
loadCommandersAndAbilities: is the method listed in the original question, I also added notifications to let my view controller know when the method has finished.
//end of loadCommandersAndAbilities
[[NSNotificationCenter defaultCenter] postNotificationName:@"TableViewDataDownloaded" object:nil];