在嵌套的NSDictionary错误中设置键的值(不可变)

时间:2014-09-16 07:54:46

标签: objective-c

所以我得到了这段代码:

self.itemsNSMutableArray

    [self.items enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSDictionary *checkin, NSUInteger index, BOOL *stop) {
        if ([checkin[@"_id"] isEqualToString:checkinID]) {
            NSMutableDictionary *checkin = (NSMutableDictionary *)self.items[index];
            NSMutableDictionary *user_data = (NSMutableDictionary *)checkin[@"user_data"];
            user_data[@"likes_checkin"] = @1;
            checkin[@"user_data"] = user_data;
            self.items[index] = checkin;
        }
    }];

但收到错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'

  1. 我不确定这个错误是怎么发生的?
  2. 我采取的方法是最好的方法吗?这看起来非常冗长......

3 个答案:

答案 0 :(得分:1)

您似乎将不可变字典转换为可变字典:

NSMutableDictionary *checkin = (NSMutableDictionary *)self.items[index];

那不行。演员表实际上不会改变对象并将其从NSDictionary更改为NSMutableDictionary。这会:

NSMutableDictionary *checkin = [self.items[index] mutableCopy];

mutableCopy,如果可用,将创建一个可变的对象的新副本。在mutableCopy上调用NSDictionary将会生成包含原始字典对象和密钥的新NSMutableDictionary

答案 1 :(得分:0)

self.itemsNSMutableArray个对象,但项目为immutable NSDictionary。您正在NSDictionary内添加self.items个对象。因此,添加NSMutableDictionary对象以获取immutability

你可以这样做:

NSDictionary *yourImmutableDictionary = [NSDictionary doSomething];

NSMutableDictionary *yourMutableDictionary = [NSMutableDictionary dictionaryWithDictionary:yourImmutableDictionary];

NSMutableDictionary *yourMutableDictionary = [yourImmutableDictionary mutableCopy];

答案 2 :(得分:0)

您正在修改数组,而正在枚举它,并且您正在尝试修改不可变字典,而不是可变字典。

如果您想要修改数组中的一个字典,那么首先找到要更改的字典的索引,然后在枚举之外更改字典:

__block NSUInteger foundIndex = NSNotFound;
[self.items enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSDictionary *checkin, NSUInteger index, BOOL *stop) {
    if ([checkin[@"_id"] isEqualToString:checkinID]) {
        foundIndex = index;
        *stop = YES;
    }
}];

if (foundIndex != NSNotFound) {
    NSMutableDictionary *checkin = [self.items[foundIndex] mutableCopy];
    NSMutableDictionary *user_data = [checkin[@"user_data"] mutableCopy];
    user_data[@"likes_checkin"] = @1;
    checkin[@"user_data"] = user_data;
    self.items[foundIndex] = checkin;
}