2014-03-05 15 views
0

我这样做很快,因为应用程序启动,幸运的是我必须在一个名为CMIDataManager的单例类中只做一次,我的应用程序启动时间太长。使用嵌套快速枚举花费时间太长,如何优化?

plist中包含:

Commanders.plist:

德语 - 阵列

苏 - 阵列

每个指挥官阵列具有19指挥官并且每个指挥官5种能力(映射通过独特的能力)。

Abilities.plist:

GermanAbilities - 阵列

SovietAbilities - 阵列

每个阵列包含40种能力与UID(用于映射指挥官能力)

在开始时,我需要创建一个模型类,所以我在每个能力隐藏中迭代指挥官的能力,一旦发现匹配,我将能力模型对象添加到Commaders模型对象。

我该如何做得更快?使用基于块的枚举会加快速度吗?我如何使用它?

-(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); 




} 

添加图片:

Commander Plist sample Abilities Plist Sample

+0

参见http://stackoverflow.com/questions/4486622/when-to-use-enumerateobjectsusingblock-vs-for – matt

+0

更多有趣的数字在这里,虽然我不知道知道他们是正确的:http:// darkdust。net/writings/objective-c/nsarray-enumeration-performance – matt

+0

你知道99%的代码是花在调用NSLog吗? – gnasher729

回答

1

好像问题是在这个循环:

 if ([ability.uid isEqualToNumber: uid]) { 

       [commander.abilitiesArray addObject:ability]; 

} 

一旦我找到指挥官的所有能力的列表能力的比赛,我并不需要检查这种能力以配合休息的能力,所以我添加了一个break语句。

  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; 
      } 

我也已将此添加代码,使其在后台线程中运行,使发射时间从6秒下降到0.5秒。

-(instancetype)init { 

self = [super init]; 

if(self) { 

    [self performSelectorInBackground:@selector(loadCommandersAndAbilities) withObject:nil]; 

    //[self loadCommandersAndAbilities]; 

    // NSOperationQueue 
} 

return self; 
} 

loadCommandersAndAbilities:在原来的问题中列出的方法,我还添加了通知,让我的视图控制器知道什么时候该方法已经完成。 loadCommandersAndAbilities的

//结束

[[NSNotificationCenter defaultCenter] postNotificationName:@"TableViewDataDownloaded" object:nil]; 
1

最明显的一点是,你的能力阵列不应该是一个数组,但一本字典。这样你就不会将uid与每种技能的uid进行比较,而是可以在一次操作中查看它。

+0

是真的,但我已经做了plist:D所以我使用break语句排序该问题。 – ManicMonkOnMac

+0

你是指在plist中还是在模型对象中加载它? – ManicMonkOnMac