2014-03-05 40 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