I am running through a list of arguments, though in these arguments the value can be anything from NSInteger, Selector to NSObjects. But if it is an NSObject it needs to be retained properly. I can't simply check if the class is the same as NSObject or if it responds to the retain method, because if you do that on a selector or integer it will simply crash. So how can you still do it? I have no idea.
I even tried to put a @try @catch in it, try to retain if not it's probably an object that doesn't need to be retained. But it crashes immediately too :( No error exception here.
If only I could test if a certain argument has a class, if a class is found I can check it for being a NSObject class, if no class is found it shouldn't be retained either. I found:
object_getClass();
But it crashes when you pass an NSInteger in it.
Looking at the NSInvocation class you can call the retainArguments method, unfortunatly this will crash the app as well. But there is something strange in the description at setArgument:
When the argument value is an object, pass a pointer to the variable (or memory) from which the object should be copied
That would mean there is 'something' that can detect if an argument is an object, but how?
Code (till now)
- (void)addObserver:(NSObject *)observer selector:(SEL)selector arguments:(id)firstObj, ... {
// Define signature
NSMethodSignature *signature = [[observer class] instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
// Prepare invocation
[invocation setTarget:observer];
[invocation setSelector:selector];
id currentObject;
va_list argumentsList;
NSInteger currentIndex = 2;
if (firstObj) {
va_start (argumentsList, firstObj);
while (currentObject = va_arg(argumentsList, id)) {
[invocation setArgument:¤tObject atIndex:currentIndex];
currentIndex++;
}
va_end(argumentsList);
}
// The observer can easily be retained by doing [observer retain];
// However the arguments may consist of NSIntegers etc. which really don't like
// to be retained (logically). So I want to skip the argument that don't need
// retaining.
}
Goal
What I am trying to accomplish is the following:
I have a random method like:
- (void)fetchFruitApples:(NSInteger)amount inRange:(NSRange)range withString:(NSString *)aString {
//Can I fetch fruit?
//If so, execute method.
//If not wait for a certain event to occur (without blocking the main thread)
//Then retry this method with the arguments passed.
//Thats why here I want to do [MyObject addObserver:self selector:@selector(fetchFruitApples:inRange:withString:) arguments:amount, range, aString, nil];
}