mutating方法发送到不可变对象 - [__NSCFDictionary setObject:forKey:]

时间:2015-11-17 09:12:17

标签: ios objective-c iphone exception nsmutabledictionary

我正在尝试更新NSMutableDictionary,但我得到了

  发送到不可变对象的

变异方法

错误。 itemMutableArrayNSMutableArray的一个实例,它包含NSMutableDictionary的实例。请帮忙。

for(NSMutableDictionary *dict in itemMutableArray){
    for (NSString *key in [dict allKeys]) {
         NSString *kv = [dict valueForKey:key];
         if([kv isEqualToString:[NSString stringWithFormat:@"%@%d",@"FIELD_",k]]) {                                      
             [dict setValue:field.text forKey:@"Value"];
         }
    }
 }

Execption:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010cb07f35 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010c574bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010cb07e6d +[NSException raise:format:] + 205
    3   CoreFoundation                      0x000000010ca3e8a3 -[__NSCFDictionary setObject:forKey:] + 99
    4   MobileWalletBanking                 0x0000000109e41c62 -[MyViewController validateConnectionFields] + 6178
    5   MobileWalletBanking                 0x0000000109e402f1 -[MyViewController validateInputFields] + 2065
    6   MobileWalletBanking                 0x0000000109e42291 -[MyViewController performBillPayment:] + 97
    7   UIKit                               0x000000010abdb8be -[UIApplication sendAction:to:from:forEvent:] + 75
    8   UIKit                               0x000000010ace2410 -[UIControl _sendActionsForEvents:withEvent:] + 467
    9   UIKit                               0x000000010ace17df -[UIControl touchesEnded:withEvent:] + 522
    10  UIKit                               0x000000010af88540 _UIGestureRecognizerUpdate + 9487
    11  UIKit                               0x000000010ac20ff6 -[UIWindow _sendGesturesForEvent:] + 1041
    12  UIKit                               0x000000010ac21c23 -[UIWindow sendEvent:] + 667
    13  UIKit                               0x000000010abee9b1 -[UIApplication sendEvent:] + 246
    14  UIKit                               0x000000010abfba7d _UIApplicationHandleEventFromQueueEvent + 17370
    15  UIKit                               0x000000010abd7103 _UIApplicationHandleEventQueue + 1961
    16  CoreFoundation                      0x000000010ca3d551 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    17  CoreFoundation                      0x000000010ca3341d __CFRunLoopDoSources0 + 269
    18  CoreFoundation                      0x000000010ca32a54 __CFRunLoopRun + 868
    19  CoreFoundation                      0x000000010ca32486 CFRunLoopRunSpecific + 470
    20  GraphicsServices                    0x000000010e14f9f0 GSEventRunModal + 161
    21  UIKit                               0x000000010abda420 UIApplicationMain + 1282
    22  MobileWalletBanking                 0x0000000109db5733 main + 115
    23  libdyld.dylib                       0x000000010dca4145 start + 1
)

3 个答案:

答案 0 :(得分:5)

你的词典显然是不是 NSMutableDictionary的一个实例,否则你不会得到那个错误。

调试规则:你认为你所知道的都是错的。

将指针声明为NSMutableDictionary *并不会使项目成为可变字典。

检查代码,将字典添加到数组中,并检查添加不可变字典的位置。

顺便说一句。阅读valueForKey和setValueForKey的文档。然后阅读objectForKey和setObjectForKey的文档。读完之后,你真的想用valueForKey吗?你是否明白它有时会做一些根本不符合你期望的事情,特别是当你无法控制钥匙时?

答案 1 :(得分:0)

正如@Paulw正确地说将其转换为NSMutableDictionary变量不会使标准字典变得可变。

试试这个: -

NSMutableDictionary *dicNew = [NSMutableDictionary new];

for(NSMutableDictionary *dict in itemMutableArray){
    for (NSString *key in [dict allKeys]) {
        NSString *kv = [dict valueForKey:key];
        if([kv isEqualToString:[NSString stringWithFormat:@"%@%d",@"FIELD_",k]]) {
            [dicNew setValue:field.text forKey:@"Value"];
        }
    }
}

答案 2 :(得分:0)

好的,问题是你的itemMutableArray不包含可变字典,我认为它将是一个普通的字典。

现在有两个选择,

1.只需将普通字典更改为可变字典,该字典将添加到itemMutableArray并继续使用您的代码。

2.使用以下代码

for(int i = 0; i < itemMutableArray.count; i++)
    {
        NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:[itemMutableArray objectAtIndex:i]];
        for (NSString *key in [dict allKeys]) {
            NSString *kv = [dict valueForKey:key];
            if([kv isEqualToString:[NSString stringWithFormat:@"%@%d",@"FIELD_",k]]) {
[dict removeObjectForKey:@"Value"];
                [dict setObject:field.text forKey:@"Value"];
            }
        }
    }