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

use*_*946 2 iphone objective-c ipad ios

我在更新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];
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

这是怎么回事?谢谢

JRG*_*per 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];
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您的字典中有大型对象(符合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];
    }
}
Run Code Online (Sandbox Code Playgroud)