Как я могу просто "проглотить" "нераспознанную ошибку селектора" при пересылке сообщений?

Я просто изучаю "пересылку сообщений" в Objective-C. Я пишу тестовую программу, чтобы проверить, могу ли я "проглотить" нераспознанный селектор во время выполнения. Итак, я сделал это:

- (void) forwardInvocation: (NSInvocation *) anInvocation {
    if ([anInvocation selector] == @selector(testMessage)){
       NSLog(@"Unknow message");
    }
    return;
}

Но все равно выдает ошибку "нераспознанный селектор" во время выполнения. После поиска разрешения я знаю, что мне нужно переопределить метод "methodSignatureForSelector:", поэтому я пишу другой прокси-класс с именем "Proxy" и следующий метод:

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    if ([Proxy instancesRespondToSelector: selector]) {
        return [Proxy instanceMethodSignatureForSelector: selector];
    }   
    return [super methodSignatureForSelector:selector];
}

Но, на самом деле, я не хочу реализовывать такой другой прокси-класс для реализации этого метода. Все, что я хочу сделать, это игнорировать этот неизвестный селектор. Но если я просто наберу это, это не сработает:

(NSMethodSignature *)methodSignatureForSelector:(SEL)selector {   
    return [super methodSignatureForSelector:selector];
}

Итак, интересно, есть ли способ, который может просто "проглотить" эту ошибку? (Не используя обработчик исключений, я хочу "переадресовать"). Спасибо!

1 ответ

Вам, вероятно, нужно сгенерировать объект подписи, что немного сложно:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    NSMethodSignature *sig = [super methodSignatureForSelector:selector];
    if (!sig) {
        if (selector == @selector(testMessage)) {
            // Create a signature for our fake message.
            sig = [NSMethodSignature signatureWithObjCTypes:"@:"];
        }
    }
    return sig;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
   // Do whatever you want with the invocation.
}

Самая большая проблема, кажется, аргумент signatureWithObjCTypes:, См . Документацию Apple по кодированию типов. Каждый метод имеет как минимум два аргумента: id self (тип @) а также SEL _cmd (тип :).

Другой способ будет иметь фиктивный метод, скажем, - (void)dummy { } а затем использовать sig = [super methodSignatureForSelector:@selector(dummy)]; чтобы получить подпись для вашего поддельного метода.

Другие вопросы по тегам