2013-05-10 3 views
0

Следующий код генерирует исключение.Неожиданное исключение с NSInvocation

vcClass является объектом Class (наследник от UIViewController). Self содержит моей реализацию из 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]; 

С сообщением:

Нагрузочного приложением из-за неперехваченное исключение 'NSInvalidArgumentException', причина: «- [NSInvocation setArgument: atIndex]: индекс (1) за пределами [-1, -1]

Дополнительная информация: iOS5, ARC. Может кто-нибудь объяснить мне, что случилось?

ОБНОВЛЕНО:

Этот код код дает мне отвечает сообщение. Итак, мой объект класса правильный [vcClass экземплярыRespondToSelector: viewWillAppearSEL]? NSLog (@ «отвечает»): NSLog (@ «не отвечает»);

Alse Im получение аварии сразу после [invocation setSelector:viewWillAppearSEL];. Вот почему я назвал название темы как Неожиданное исключение с NSInvocation.

UPDATED2:

Также моя реализация из 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"); 
} 
+0

Это означает, что у вас есть неправильный класс в 'vcClass', и он не реализовал этот селектор. –

+0

'[vcClass instanceRespondToSelector: viewWillAppearSEL]? NSLog (@ «отвечает»): NSLog (@ «не отвечает»); ' Возвращает **« отвечает »** сообщение – user1248568

+0

@lxt нет, он хочет использовать vc, а не вид - также я не знаю, Если вы видите ошибку в 4 строках, указанных выше. он падает, когда вы устанавливаетеArgument –

ответ

1

Одна из проблем с вашим кодом является тип кодирования, который вы передаете в class_addMethod(). Кодирование этого типа должно включать: 1) тип возврата, 2) типы для self и _cmd (первые два скрытых параметра), а затем 3) типы всех других параметров.

Для метода, как - (void)viewWillAppear:(BOOL)animated, кодирующий тип должен быть строкой

[email protected]:c

  • v - для void, возвращаемый тип
  • @ - для id, типа для self
  • : - для SEL, тип для _cmd
  • c - для char, это то, что BOOL есть. Это то, что вы получили, когда вы сделали @encode(BOOL)
1

BOOL * arg1;

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; 
[invocation setSelector:viewWillAppearSEL]; 
[invocation setArgument:&arg1 atIndex:2]; // argument indexing is offset by 2 hidden args 
+0

. Прокомментируйте свой ответ. – user1248568

+0

вот в чем проблема. -viewWillAppear: принимает 1 аргумент, а вызов не содержит –

+1

@ art-divin, и? Я получаю исключение сразу после '[invocation setSelector: viewWillAppearSEL];' – user1248568

 Смежные вопросы

  • Нет связанных вопросов^_^