Skip to content

Loading…

Fix request descriptor lookup class matching. #1692

Closed
wants to merge 1 commit into from

4 participants

@deanbrowne

Class matching was done based on address equality of the Class.
Almost always that is enough, but two different Class structs can be
created to represent the same thing. When this happens RestKit could
not match the registered RequestDescriptor.

This happened to me and I have no way to create a good reproducable
test. I found a StackOverflow
thread
on this happening.

@deanbrowne deanbrowne Fix request descriptor lookup class matching.
`Class` matching was done based on address equality of the `Class`.
Almost always that is enough, but two different `Class` structs can be
created to represent the same thing.  When this happens RestKit could
not match the registered `RequestDescriptor`.

This happened to me and I have no way to create a good reproducable
test.  I found a [StackOverflow
thread](http://stackoverflow.com/questions/16424298/why-is-class-nsclass
fromstringnsstringfromclass-class-on-os-x) on this happening.
b200d3c
@segiddins
The RestKit Project member

@deanbrowne before we think about merging this, could you please add a failing unit test? Thanks

@deanbrowne
@segiddins
The RestKit Project member

@deanbrowne without a failing test, I'm hesitant to merge in any changes

@percysnoodle
The RestKit Project member

@deanbrowne I had a problem a few weeks ago, not related to RestKit, where I'd accidentally added a .m file from one of my pods to my main target, and so I had two copies of the same class, and it was causing weird problems in places where I was calling isKindOfClass:. Perhaps something similar happened to you with your unit tests?

I'm not sure testing by class name is the best way of checking for this, though; it seems to me that having two classes with the same name but different implementations is just as likely as having two copies of the same class, if not more so.

@percysnoodle
The RestKit Project member

@deanbrowne if you want to write a test for multiple classes with the same name, have a look at objc_allocateClassPair and objc_registerClassPair - there's an example of them in use here.

@blakewatters
The RestKit Project member

Comparing classes should be sufficient. This probably indicates that you actually have two copies of the class compiled in somehow and are getting different versions randomly. This can happen if you compile one into a static library/testing bundle and another copy into the main app target.

I believe this to be an issue on the user side and do not want to merge any changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 29, 2013
  1. @deanbrowne

    Fix request descriptor lookup class matching.

    deanbrowne committed
    `Class` matching was done based on address equality of the `Class`.
    Almost always that is enough, but two different `Class` structs can be
    created to represent the same thing.  When this happens RestKit could
    not match the registered `RequestDescriptor`.
    
    This happened to me and I have no way to create a good reproducable
    test.  I found a [StackOverflow
    thread](http://stackoverflow.com/questions/16424298/why-is-class-nsclass
    fromstringnsstringfromclass-class-on-os-x) on this happening.
This page is out of date. Refresh to see the latest.
Showing with 10 additions and 5 deletions.
  1. +10 −5 Code/Network/RKObjectManager.m
View
15 Code/Network/RKObjectManager.m
@@ -84,13 +84,18 @@
RKRequestDescriptor *RKRequestDescriptorFromArrayMatchingObjectAndRequestMethod(NSArray *requestDescriptors, id object, RKRequestMethod requestMethod)
{
Class searchClass = [object class];
+ NSString *searchClassName = NSStringFromClass(searchClass);
do {
for (RKRequestDescriptor *requestDescriptor in requestDescriptors) {
- if ([requestDescriptor.objectClass isEqual:searchClass] && (requestMethod == requestDescriptor.method)) return requestDescriptor;
- }
-
- for (RKRequestDescriptor *requestDescriptor in requestDescriptors) {
- if ([requestDescriptor.objectClass isEqual:searchClass] && (requestMethod & requestDescriptor.method)) return requestDescriptor;
+ BOOL matchesRequestMethod = requestMethod & requestDescriptor.method;
+ if (matchesRequestMethod) {
+ Class requestDescriptorClass = requestDescriptor.objectClass;
+ NSString *requestDescriptorClassName = NSStringFromClass(requestDescriptorClass);
+ BOOL matchesClass = [requestDescriptorClassName isEqualToString:searchClassName];
+ if (matchesClass) {
+ return requestDescriptor;
+ }
+ }
}
searchClass = [searchClass superclass];
} while (searchClass);
Something went wrong with that request. Please try again.