Using valueForKeyPath on NSDictionary if a key sta

2019-01-23 13:17发布

I want to use valueForKeyPath on my NSDictionary, but the problem is that one of the keys is a string that starts with the @ symbol. I have no control over the naming of the key.

I'm having problems trying to create the key path as I'm getting a format exception, even when trying to escape the @ symbol:

This works fine:

[[[dict objectForKey:@"key1"] objectForKey:@"@specialKey"] objectForKey:@"key3"]

However none of these work:

[dict valueForKeyPath:@"key1.@specialKey.key3"]
[dict valueForKeyPath:@"key1.@@specialKey.key3"]

Any ideas?

Thanks,

Mike

4条回答
时光不老,我们不散
2楼-- · 2019-01-23 13:55

If you have no control over the naming, how about adding a category with a properly named key that simply returns/sets the weird key?

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-23 14:05

you shouldn't be using @ signs with your key names if you want to use key value coding.

apple's guidelines for key names are as follows:

Keys must use ASCII encoding, begin with a lowercase letter, and may not contain whitespace.

You'll have to find a workaround to reformat the key string whereever you're getting your keys from to be KVC compliant.

查看更多
孤傲高冷的网名
4楼-- · 2019-01-23 14:07

I see that there are 2 ways

Swizzle

You can swizzle the valueForKeyPath on NSDictionary to remove the @ symbol, remember to account for @sum, @average, ...

Override if you're using Mantle

Override + (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary on MTLJSONAdapter, traverse all the keys and remove the @ symbol

查看更多
对你真心纯属浪费
5楼-- · 2019-01-23 14:08

Just to update this old question a little...

The reason that these:

[dict valueForKeyPath:@"key1.@specialKey.key3"]
[dict valueForKeyPath:@"key1.@@specialKey.key3"]

...fail is that any "@" symbols in a key path are interpreted as being collection's operators as with:

[dict valueForKeyPath:@"key1.@sum.key3"] // returns the sum of all 'key3' values
[dict valueForKeyPath:@"key1.@avg.key3"] // returns the average of all 'key3' values

The nested key calls:

[[[dict objectForKey:@"key1"] objectForKey:@"@specialKey"] objectForKey:@"key3"]

... work because a single key is not processed as a key path.

查看更多
登录 后发表回答