2012-09-12 134 views
1
- (NSMutableDictionary *)updateTemplates:(NSMutableDictionary *)oldTemplates 
          forSpecType:(NSString *)specType { 
    // oldTemplates is an NSMutableDictionary pulled from a plist 
    // specType is used for flexible paths, to eliminate duplicate code 

    // Make a dict of the parameters object (about to be overwritten) 
    NSMutableDictionary *parameters = [oldTemplates valueForKeyPath: 
        [NSString stringWithFormat:@"root.%@.parameters", specType]]; 

    // Dump the new data into the matching object 
    [oldTemplates setValue:[updateTemplates valueForKeyPath: 
           [NSString stringWithFormat:@"data.%@", specType]] 
       forKeyPath:[NSString stringWithFormat:@"root.%@", specType]]; 

    // Put the parameters back, since they don't exist anymore 
    /* Instant crash, with the debugger claiming something is immutable 
    * But I just used the exact same method on the line above 
    * updateTemplates isn't immutable either; it's only when I try to mutate 
     oldTemplates after putting in updateTemplates -- and only the update 
     seems to be breaking things -- that I get the exception and crash 
    */ 
    [oldTemplates setValue:parameters forKeyPath: 
        [NSString stringWithFormat:@"root.%@.parameters", specType]]; 

    return oldTemplates; 
} 

我就可以建立一个循环来写的updateTemplates.specType一个对象在一个时间,所以只有那些部分被替换,然后我不知道必须对参数做任何事情,但是如果它现在是不可变的,那么当我尝试再次写入它时将会如此。这对我没有任何好处。“ - [__ NSCFDictionary的setObject:forKey:]:变异的方法发送到不可变对象”

+0

这可能是件好事同时记录'oldTemplates'和'parameters'只是为了看看什么类型的运行时间认为他们是。 (错误是否给出了对象地址?如果是这样,它是否与您在此代码中使用的其中一个字典匹配?) –

回答

3

mutableCopy让一个浅可变的副本,而不是一个深刻的可变副本。如果您的NSDictionary包含值为NSDictionary实例的键/值对,则mutableCopy将返回包含那些不可变实例作为值的可变字典。

您可能需要执行深层复制或使用plist序列化功能来解码启用了可变集合选项的plist。或者你可以撰写一个从旧的派生出来的新集合。

+0

我确实有NSJSONSerialization与kNilOptions一起运行。哎呀。 – Thromordyn

4

如果我没有记错,默认情况下从plists或NSUserDefaults创建的字典是不可变的。你必须手动创建一个可变副本:

NSMutableDictionary *parameters = [[oldTemplates valueForKeyPath: 
      [NSString stringWithFormat:@"root.%@.parameters", specType]] mutableCopy]; 
+0

无关紧要。在其他地方,我从plist得到一个NSMutableDictionary,我可以正常地修改它。 - Xcode只是再次冻结。 - 如果我尝试在'updateTemplates'上调用'setObject:forKey:',它会一直运行,我可以记录该对象。所以更新不是不可变的。嗯。 – Thromordyn

0

你可以简单地做:

NSMutableDictionary* oldTemplates = [NSMutableDictionary dictionaryWithDictionary:[oldTemplates valueForKeyPath: 
        [NSString stringWithFormat:@"root.%@.parameters", specType]]]; 

这将从现有的NSDictionary创建副本可变

+0

试过了。没有改变任何东西。 – Thromordyn

相关问题