Question

Following code throws an exception.

vcClass is a Class object (inheritor from UIViewController). Self contains my implementation of viewWillAppear:

SEL viewWillAppearSEL = @selector(viewWillAppear:);
IMP viewWillAppearWithSuperIMP = [self methodForSelector:viewWillAppearSEL];
class_addMethod(vcClass, viewWillAppearSEL, viewWillAppearWithSuperIMP, @encode(BOOL));
NSMethodSignature *methodSignature = [vcClass instanceMethodSignatureForSelector:viewWillAppearSEL];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setSelector:viewWillAppearSEL];

With message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSInvocation setArgument:atIndex:]: index (1) out of bounds [-1, -1]

Additional info: iOS5, ARC. Can someone explain me what's wrong?

UPDATED:

This code code gives me responds message. So my class object is correct [vcClass instancesRespondToSelector:viewWillAppearSEL] ? NSLog(@"responds") : NSLog(@"not responds");

Alse Im getting crash right after [invocation setSelector:viewWillAppearSEL];. That's why I called topic title as Unexpected exception with NSInvocation.

UPDATED2:

Also my implementation of viewWillAppear:

- (void)viewWillAppear:(BOOL)animated {
    Class parentViewController = [self superclass];
    void (*superViewWillAppear)(id, SEL, BOOL) =(void(*)(id, SEL, BOOL))class_getMethodImplementation(parentViewController, _cmd);
    superViewWillAppear(self, _cmd, animated);
    NSLog(@"view will appear with super");
}
Was it helpful?

Solution

One problem with your code is the type encoding that you are passing to class_addMethod(). This type encoding must include: 1) the return type, 2) the types for self and _cmd (the first two hidden parameters), and then 3) the types of all the other parameters.

For a method like - (void)viewWillAppear:(BOOL)animated, the type encoding should be the string

v@:c

  • v -- for void, return type
  • @ -- for id, type for self
  • : -- for SEL, type for _cmd
  • c -- for char, this is what BOOL is. This is what you get when you did @encode(BOOL)

OTHER TIPS

BOOL *arg1;

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setSelector:viewWillAppearSEL];
[invocation setArgument:&arg1 atIndex:2];   // argument indexing is offset by 2 hidden args
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top