Ios &引用;“发送到不可变对象的变异方法”;只在一段时间后出错?

Ios &引用;“发送到不可变对象的变异方法”;只在一段时间后出错?,ios,objective-c,nsdictionary,Ios,Objective C,Nsdictionary,所以,我的问题是,只有在分段之后,我的代码才会与NSDictionary混淆。程序将得到嵌套的if语句,但在这之后,它会给我“Mutating method sent to immutable object”错误。这只会在一段时间后发生在我身上。如果我不把程序分段,它就可以正常工作。这是我的didSelectRowAtIndexPath - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath

所以,我的问题是,只有在分段之后,我的代码才会与NSDictionary混淆。程序将得到嵌套的if语句,但在这之后,它会给我“Mutating method sent to immutable object”错误。这只会在一段时间后发生在我身上。如果我不把程序分段,它就可以正常工作。这是我的didSelectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSNumber *boolNumberYes = [NSNumber numberWithBool:YES];
    NSNumber *boolNumberNO = [NSNumber numberWithBool:NO];


    NSMutableArray *currentSectionArray = [self.sectionArrays objectAtIndex:indexPath.section];
    NSString *currentStringSubject = [self.subjectArray objectAtIndex:indexPath.section];

    NSMutableDictionary *tempDic = [self.mainDictionary objectForKey:currentStringSubject];


    NSArray *temp = [tempDic allKeysForObject:[currentSectionArray objectAtIndex:indexPath.row]];
    NSString *key = [temp lastObject];

    NSMutableDictionary *tempCompleted = [self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]];

    if (!tempCompleted) {
        NSLog(@"DOESNT EXIST");

        tempCompleted = [[NSMutableDictionary alloc] initWithObjectsAndKeys: boolNumberNO, [NSString stringWithFormat:@"Completed %@",currentStringSubject],nil];
        [self.mainDictionary setObject:tempCompleted forKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]];
    }


    NSLog(@"key %@",key);


    NSString *currentString = [tempDic objectForKey:key];
    NSLog(@"current %@",currentString);


    if ([tempCompleted objectForKey:[NSString stringWithFormat:@"Completed %@",currentString]]) {
        NSLog(@"completed exists");

        BOOL bValue = [[tempCompleted objectForKey:[NSString stringWithFormat:@"Completed %@",currentString]] boolValue];


        NSLog(@"MAINDIC %@",self.mainDictionary);

        if (bValue == NO) {
            NSLog(@"CHANGED TO YES");

            NSLog(@"TEMPCOMPL%@",tempCompleted);
            NSLog(@"currentString %@",currentString);
            [tempCompleted setObject:boolNumberYes forKey:[NSString stringWithFormat:@"Completed %@",currentString]];

            NSLog(@"MAINDICYES %@",self.mainDictionary);
        }
        else if (bValue == YES) {
            NSLog(@"CHANGED TO NO");
            NSLog(@"TEMPCOMPL%@",tempCompleted);
            NSLog(@"currentString %@",currentString);
            [tempCompleted setObject:boolNumberNO forKey:[NSString stringWithFormat:@"Completed %@",currentString]];

            NSLog(@"MAINDICNO %@",self.mainDictionary);
        }


    }
    else{
        NSNumber *boolNumber = [NSNumber numberWithBool:YES];
        [tempCompleted setObject:boolNumber forKey:[NSString stringWithFormat:@"Completed %@",currentString]];

    }


    [self.mainDictionary setObject:tempCompleted forKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]];
    [[NSUserDefaults standardUserDefaults] setObject:self.mainDictionary forKey:[NSString stringWithFormat:@"mainDictionary%@",self.todayString ]];
    [[NSUserDefaults standardUserDefaults]synchronize];
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    [tableView reloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationNone];

}
还有我的日志

2014-05-05 13:31:40.807 AgendaBk[44203:90b] CHANGED TO YES
2014-05-05 13:31:40.807 AgendaBk[44203:90b] TEMPCOMPL{
    "Completed + Button to Add" = 0;
    "Completed Swipe to Delete" = 0;
    "Completed Test 1" = 0;
    "Completed Test 2" = 0;
}
2014-05-05 13:31:40.807 AgendaBk[44203:90b] currentString Test 1
2014-05-05 13:31:40.809 AgendaBk[44203:90b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

问题应该是这个字符串:

NSMutableDictionary *tempCompleted = [self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]];
确保当您从
main字典
获取此对象时,它是一个
NSMutableDictionary
,否则它是一个
NSDictionary
,并且是不可变的

如果是不可变的,请检查您的代码,或者您也可以使用可变副本进行求解,如:

NSMutableDictionary *tempCompleted = [[self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]] mutableCopy];

尝试更改此行:

[self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]]
对于这一点:

[[self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]] mutableCopy]

确保您的self.mainDictionary是类NSMutableDictionary

换行

NSMutableDictionary *tempCompleted = [self.mainDictionary objectForKey:[NSString stringWithFormat:@"Completed %@",currentStringSubject]];


下面介绍如何创建数组或字典的深度副本,以便容器也可以更改:

yourDictionary = (NSMutableDictionary *) CFBridgingRelease(
  CFPropertyListCreateDeepCopy(
    kCFAllocatorDefault, (CFDictionaryRef)yourDictionary, 
    kCFPropertyListMutableContainers
  )
);

错误很明显。您正在不可变的
NSMutableDictionary
上调用
setObject:forKey:
,而不是可变的
NSMutableDictionary
。但是
tempCompleted
NSMutableDictionary
显然不是。仅仅因为您将它声明为一个
NSMutableDictionary
,并不意味着它是一个可变字典。不,它不是。如果是这样的话,你就不会出错了。好吧,谢谢你修复了它,真奇怪,我以前从未经历过这种情况。mainDictionary是可变的,我不明白为什么会出现这个错误。太好了,谢谢@user3430084仅仅因为
mainDictionary
是可变的,并不意味着其中的其他容器是可变的。如果您展示如何创建/加载
mainDictionary
,这会有所帮助。确切地说,重要的是您的字典包含什么。
yourDictionary = (NSMutableDictionary *) CFBridgingRelease(
  CFPropertyListCreateDeepCopy(
    kCFAllocatorDefault, (CFDictionaryRef)yourDictionary, 
    kCFPropertyListMutableContainers
  )
);