0

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");
}
user1248568
  • 621
  • 1
  • 9
  • 29

2 Answers2

1

BOOL *arg1;

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setSelector:viewWillAppearSEL];
[invocation setArgument:&arg1 atIndex:2];   // argument indexing is offset by 2 hidden args
Thilina Chamath Hewagama
  • 9,039
  • 3
  • 32
  • 45
  • Сan u please comment your answer? – user1248568 May 10 '13 at 12:57
  • that's the issue for sure. -viewWillAppear: accepts 1 argument, and invocation doesn't contain any – art-divin May 10 '13 at 12:57
  • 1
    @art-divin, And? Im getting exception right after `[invocation setSelector:viewWillAppearSEL];` – user1248568 May 10 '13 at 12:59
  • set the second argument as specified in this answer so your invocation will contain enough data to actually invoke the method – art-divin May 10 '13 at 13:00
  • 1
    @art-divin: you are completely misunderstanding what the OP is saying. He is not getting the exception on trying to run the invocation. He is unable to set a selector in the first place. – newacct May 10 '13 at 23:35
1

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)
newacct
  • 119,665
  • 29
  • 163
  • 224