Ios4 枚举时替换数组中的对象?

Ios4 枚举时替换数组中的对象?,ios4,iphone-sdk-3.0,enumeration,Ios4,Iphone Sdk 3.0,Enumeration,我正在发送我的应用程序的更新,该更新要求更新用户数据库。我正在属性列表中存储数据。基本上数组中的每个点都是NSMutableDictionary,我需要添加键、替换键等 我尝试了以下操作,但是它生成了一个NSException for (NSMutableDictionary *dict in myArray) { if ([dict objectForKey:@"someKey"] == nil) { //Extract the value of the old k

我正在发送我的应用程序的更新,该更新要求更新用户数据库。我正在属性列表中存储数据。基本上数组中的每个点都是NSMutableDictionary,我需要添加键、替换键等

我尝试了以下操作,但是它生成了一个NSException

for (NSMutableDictionary *dict in myArray) {

    if ([dict objectForKey:@"someKey"] == nil) {

        //Extract the value of the old key and remove the old key
        int oldValue = [[dict objectForKey:@"key1"] intValue];
        [dict removeObjectForKey:@"key1"];

        [dict setValue:[NSString stringWithFormat:@"%d pts", oldValue] forKey:@"newKey"];

        //Add new keys to dictionnary
        [dict setValue:@"some value" forKey:@"key2"];
        [dict setValue:@"some value" forKey:@"key3"];
        [dict setValue:@"some value" forKey:@"key4"];

        [self.myArray replaceObjectAtIndex:index withObject:dict];

    }

我应该如何以上述方式更新数据?

首先,确保
myArray
是一个NSMutableArray。如果是这样的话,如果调试代码,您可能会看到一些错误,例如
\u NSArrayI发送到实例的未识别选择器
\u NSArrayI表示它是一个不可变数组。这很烦人,但是试着通过这样做来测试。然后,您可以将myArray替换为mutableArray

NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:self.myArray];
for (NSMutableDictionary *dict in mutableArray) {

if ([dict objectForKey:@"someKey"] == nil) {

    //Extract the value of the old key and remove the old key
    int oldValue = [[dict objectForKey:@"key1"] intValue];
    [dict removeObjectForKey:@"key1"];

    [dict setValue:[NSString stringWithFormat:@"%d pts", oldValue] forKey:@"newKey"];

    //Add new keys to dictionnary
    [dict setValue:@"some value" forKey:@"key2"];
    [dict setValue:@"some value" forKey:@"key3"];
    [dict setValue:@"some value" forKey:@"key4"];

    [mutableArray replaceObjectAtIndex:index withObject:dict];

}
}

问题是您无法使用快速枚举修改正在迭代的数组

代码段根本不需要调用
replaceObjectAtIndex:withObject:
调用,因为您将对象替换为完全相同的对象!所以,如果你去掉那条线,一切都会好起来

一般来说,如果使用带有索引的普通旧for循环,就可以避免类似的问题,即

for (int i = 0; i < [array count]; i++) {
    id obj = [array objectAtIndex:i];
    // ...
}
for(int i=0;i<[数组计数];i++){
id obj=[array objectAtIndex:i];
// ...
}

因为这不会影响快速枚举。

创建数组的副本并通过副本进行枚举。通过这种方式,您可以安全地修改原始文件:

for (id obj in [NSArray arrayWithArray:entries]) {
    [entries removeObject:obj];
}
不要使用:

for (int i = 0; i < [array count]; i++) {
    id obj = [array objectAtIndex:i];
    [array removeObject:obj];
}
for(int i=0;i<[数组计数];i++){
id obj=[array objectAtIndex:i];
[数组移除对象:obj];
}

这样做是因为删除后,数组索引将被偏移

根本解决不了问题。你真的应该知道你处理的对象是可变的还是不可变的。这不是一个令人烦恼的问题,这是一个非常明确和有意义的区别。我完全理解应该声明为NSMutableArray,但我怀疑他创建了一个
@属性(非原子,复制)NSMutableArray*myArray
copy
实际上将创建一个不可变数组,而不是运行代码时可以看到的NSMutableArray。您将看到底层的具体类实现是
\u NSArrayI
,在这种情况下,正确的解决方法是正确地实现setter方法。仅仅在这里制作一个可变副本并不能解决问题本身。它宁愿掩盖这个bug,难道你不能抛出一个
if
语句,并在其中删除对象和
i--