无法从for-in循环中更新NSMutableDictionary值?

时间:2013-04-08 21:10:11

标签: iphone ios objective-c ipad

我在更新NSMutableDictionary值时遇到了一个奇怪的问题。我正在运行for-in循环,一切都很好,我的数学很好。

问题出在我尝试使用setValue: forKey:方法更新字典时。

for(NSString *key in self.planetDictionary){
         if(![key isEqualToString:planet]){ 

             * * *
            //do some math and stuff, create an NSNumber:
             NSNumber *update = [NSNumber numberWithFloat:updatedProbability];

             //Problem code, EXC_BAD_ACCESS here:
             [self.planetDictionary setValue:update forKey:key];
        }
    }

我得到EXC_BAD_ACCESS崩溃。我可以确认其他一切都很好,它只是我尝试更新值的单行。

发生了什么事?感谢

3 个答案:

答案 0 :(得分:8)

您不能改变您快速枚举的对象。它每次都会崩溃。作为一种解决方法,您可以先复制一份:

NSDictionary *dictionary = [self.planetDictionary copy];

for (NSString *key in dictionary) {
     if (![key isEqualToString:planet]) {              
         NSNumber *update = [NSNumber numberWithFloat:updatedProbability];
         [self.planetDictionary setValue:update forKey:key];
    }
}

或者,如果您的词典中有大型对象(符合NSCopying,或者它只是一个浅层副本并且无关紧要),因此您不想复制所有的对象,然后你可以简单地复制键(作为一个数组),并像这样枚举它们:

NSArray *keysCopy = [[self.planetDictionary allKeys] copy];

for (NSString *key in keysCopy) {
    if (![key isEqualToString:planet]) { 
        NSNumber *update = [NSNumber numberWithFloat:updatedProbability];
        [self.planetDictionary setValue:update forKey:key];
    }
}

答案 1 :(得分:2)

看起来你在枚举它时会改变它。

在循环播放时,无法更改NSDictionary。

您可能希望在循环之前复制它,并在更改原始文件时枚举副本。

答案 2 :(得分:2)

在for循环中使用它时无法更新它。使用字典键的副本在for循环中使用并更新for循环中的原始文件。