【问题标题】:using nested fast enumeration takes too long, how to optimize?使用嵌套快速枚举耗时太长,如何优化?
【发布时间】:2014-03-05 18:38:43
【问题描述】:

我在应用程序启动后立即执行此操作,幸运的是我只需在名为 CMIDataManager 的单例类中执行一次,我的应用程序启动时间太长。

plist 包含:

Commanders.plist:

德语 - 数组

苏联 - 阵列

每个指挥官阵列有 19 个指挥官,每个指挥官有 5 种能力(通过唯一的能力 uid 映射)。

能力.plist:

德语能力 - 数组

SovietAbilities - 数组

每个数组包含 40 个具有 uid 的技能(用于将指挥官映射到技能)

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

我怎样才能更快地做到这一点?使用基于块的枚举会加快速度吗?我该如何使用它?

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




}

添加图片:

【问题讨论】:

标签: ios objective-c arrays for-in-loop fast-enumeration


【解决方案1】:

显而易见的是,你的能力数组不应该是一个数组,而是一个字典。这样您就不用将 uid 与每个能力的 uid 进行比较,而是在一次操作中查找它。

【讨论】:

  • 确实如此,但我已经制作了 plist :D 所以我使用 break 语句对该问题进行了排序。
  • 您的意思是在 plist 中还是在将其加载到模型对象中时?
【解决方案2】:

似乎问题出在这个循环中:

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

                [commander.abilitiesArray addObject:ability];

}

一旦我在所有能力列表中找到了指挥官能力的匹配项,我就不需要检查该能力是否与其他能力匹配,所以我添加了一个中断语句。

            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: 是原始问题中列出的方法,我还添加了通知让我的视图控制器知道该方法何时完成。

//加载CommandersAndAbilities结束

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-06
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多