RestKit/RestKit — pull request #2093 by carllindberg (2014-11-16 06:12:10+00:00)
Title: RKDynamicMapping enhancements

One of the more expensive mappings we have in our app makes use of a few RKDynamicMappings, sometimes with a number of possibilities on the same key path. Instead of adding a number of RKObjectMappingMatcher instances to be searched iteratively, add a new RKObjectMappingMatcher subclass which can take a value to RKObjectMapping dictionary, so a single lookup can find the appropriate matcher. This does help performance a bit, especially when there are many possibilities. The #2065 test application does not use dynamic mappings, so this has no effect there, but there is one in my app (maybe 1.15 seconds to 1.10).

To support the -objectMappings method of RKDynamicMapping, this required adding a new method to RKObjectMappingMatcher which can supply an array of possible RKObjectMappings to be returned. The abstract implementation should be good enough to support existing classes. Additionally, made that RKDynamicMapping method return a constant array instead of creating a new one every call, as it gets called during the mapping process. Although, I think it is only called once or twice by RKObjectManager when first creating the operations, so it may not be that much of a help, and maybe it would be better to continue to calculate it at runtime rather than maintain an internal array.

A couple of our mappings make use of the representation block of RKDynamicMapping, but do not use CoreData. This runs a little afoul of some code in RKObjectManager which determines whether a CoreData mapping is being used or not:
```
static BOOL RKDoesArrayOfResponseDescriptorsContainEntityMapping(NSArray *responseDescriptors)
{
[...]
if ([mapping isKindOfClass:[RKDynamicMapping class]]) {
RKDynamicMapping *dynamicMapping = (RKDynamicMapping *)mapping;
if ([dynamicMapping.objectMappings count] == 0) {
// Likely means that there is a representation block, assume `YES`
return YES;
}
}
}
```

So, if a representation block is used in a non-CoreData operation, that code will guess wrong. The effect isn't too bad, but it generates a warning log since it thinks a CoreData operation is in progress but a managed object context is not supplied. So... also added an API so that a list of RKObjectMappings can be passed in with a representation block, again to better support the -objectMappings method, and at least afford the opportunity to avoid the warning. I don't know enough about how important the above code is otherwise.