Search code examples
objective-cpass-by-referenceperformselector

iOS - Pass reference in performselector


I have the following problem and could not solve it, perhaps someone knows a trick :)

The main object has to be dynamic, because it could be different ...

Function which should be called:

+ (NSArray *)parseJSONString:(NSString *)theJSONString error:(NSError **)errorPointer

As the code already declares, I want to parse JSON. I have several objects which are implementing this function, that's why I use the performSelector method:

if ([[self.theObject class] respondsToSelector:@selector(parseJSONString:error:)]) {
     NSError *parsingError = nil;
     self.myObjectsCollection = [[self.theObject class] performSelector:@selector(parseJSONString:)
                                                             withObject:utf8ResponseString
                                                             withObject:parsingError];        
}

utf8ResponseString contains the JSON ...

I already tried the following:

... withObject:&parsingError -> compile error
... withObject:[NSValue valueWithPointer:&parsingError] -> works until the value will be redirect to the parsingError -> Bad Exec

I have searched for a day and not even have a clou on how to solve this - please help...

Thanks and greetings, mathew


Solution

  • The performSelector:... family of methods only take object arguments. You want to pass a pointer to a pointer, which isn't the same thing as an object, so the type system doesn't allow it. Fortunately, you don't need performSelector: here at all. You can just do [[self.theObject class] parseJSONString:utf8ResponseString error:&parsingError].

    You only need to use performSelector: when the message you want to send isn't known until runtime. If you're not passing in a variable as the first argument, you probably don't need it.

    However, if you did need to do this, what you'd need to do is write a "wrapper" method that takes an object (say, an NSValue) and calls the real method with the non-object type, and you'd call the wrapper instead of the real method with your performSelector:withObject:.