Why doesn't setValue:forKeyPath invoked on mutable dictionary throw exception for unknown keypaths?

微笑、不失礼 提交于 2019-12-12 17:07:59

问题


I have following code:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[defs setObject:[NSNumber numberWithInt:100] forKey:@"test1.test2.test3"];
[defs setValue:[NSNumber numberWithInt:10] forKeyPath:@"test2.test3.test4"];

I understand that setObject:forKey: creates association between "test1.test2.test3" key and given number object. On the other hand, setValue:forKeyPath: is Key-Value-Coding method that tries to locate object for path "test2.test3.test4", but in the end, it just silently does nothing. It doesn't even modify the dictionary!

What confuses me greatly is that setValue:forKeyPath: doesn't raise any exception nor does it report any error. Why is this? Is this behavior documented anywhere?


回答1:


I can't find any documentation for this specific case, sorry, but my guess is that this:

[defs setValue:x forKeyPath:@"a.b.c"];

Is being implemented something like this:

[[defs objectForKey:@"a"] setValue:x forKeyPath:@"b.c"];

So objectForKey: returns nil, and methods called on nil just do nothing. That would explain the behaviour you have described.




回答2:


NSMutableDictionary *dict = [@{@"test1" : [@{@"test2":[@{} mutableCopy]} mutableCopy]} mutableCopy];

[dict setValue:@(100) forKeyPath:@"test1.test2.test3"]; // ok
[dict setValue:@(200) forKeyPath:@"test1.test2.test4"]; // ok
[dict setValue:@(300) forKeyPath:@"test1.test21"];      // ok
[dict setValue:@(400) forKeyPath:@"test1.test22.test3"]; // fail, test22 not mutable

[dict setValue:[@{} mutableCopy] forKeyPath:@"test1.test23"]; // ok
[dict setValue:@(500) forKeyPath:@"test1.test23.test34"]; // ok


来源:https://stackoverflow.com/questions/5755917/why-doesnt-setvalueforkeypath-invoked-on-mutable-dictionary-throw-exception-fo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!