Using valueForKeyPath on NSDictionary if a key starts the @ symbol?

后端 未结 5 2060
温柔的废话
温柔的废话 2020-12-15 19:04

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 cont

相关标签:
5条回答
  • 2020-12-15 19:22

    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.

    0 讨论(0)
  • 2020-12-15 19:29

    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?

    0 讨论(0)
  • 2020-12-15 19:30

    In my humble opinion, the whole discussion here goes the wrong way Accessing entries in an NSDictionary via key paths - is simply not part of KVC protocol.

    KVC defines how to name your properties of an object, so that KVC can work. an entry in an NSDictionary is not a property, and has no name. NSDictionary adds its bit of magic to the KVC-like behaviour, by "pretending" the keys of its entries are like 'properties' of the dictionary.

    Alas, properties have different naming conventions and limitations than dictionary keys.

    If you cannot force the dictionary keys to conform with KVC-supported property names - break your key paths, and use the accessors instead where in doubt.

    That, I think, should be the safest way to go. KVC is generally a "nicety" being able to shorten your code - but it does NOT provide any functionality you cannot have otherwise (as you demonstrated yourself).

    0 讨论(0)
  • 2020-12-15 19:34

    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

    0 讨论(0)
  • 2020-12-15 19:48

    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.

    0 讨论(0)
提交回复
热议问题