Set default handler for "unrecognized selector" exception
Asked Answered
A

3

5

In Objective-C, is there a way to set a default hander to avoid unrecognizedselector exception ? I want to make the NSNULL and NSNumber to response all the methods in NSString.

Thanks!

Arachne answered 15/11, 2012 at 4:2 Comment(0)
A
3

To handle the "unrecognized selector" exception, we should override two methods:

- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector;

In this case, if we want NSNull to perform the NSSString method if "unrecognized selector" exception occurred, we should do this:

@interface NSNull (InternalNullExtention)
@end



@implementation NSNull (InternalNullExtention)

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
    NSMethodSignature* signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        signature = [@"" methodSignatureForSelector:selector];
    }
    return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL aSelector = [anInvocation selector];

    if ([@"" respondsToSelector:aSelector])
        [anInvocation invokeWithTarget:@""];
    else
        [self doesNotRecognizeSelector:aSelector];
}
@end
Arachne answered 15/11, 2012 at 6:1 Comment(0)
M
3

You can use categories to add methods to the NSNull and NSNumber classes. Read about categories in The Objective-C Programming Language.

You can implement methodSignatureForSelector: and forwardInvocation: to handle any message without explicitly defining all of the messages you want to handle. Read about them in the NSObject Class Reference.

Mala answered 15/11, 2012 at 4:22 Comment(0)
A
3

To handle the "unrecognized selector" exception, we should override two methods:

- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector;

In this case, if we want NSNull to perform the NSSString method if "unrecognized selector" exception occurred, we should do this:

@interface NSNull (InternalNullExtention)
@end



@implementation NSNull (InternalNullExtention)

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
    NSMethodSignature* signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        signature = [@"" methodSignatureForSelector:selector];
    }
    return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    SEL aSelector = [anInvocation selector];

    if ([@"" respondsToSelector:aSelector])
        [anInvocation invokeWithTarget:@""];
    else
        [self doesNotRecognizeSelector:aSelector];
}
@end
Arachne answered 15/11, 2012 at 6:1 Comment(0)
B
1

There is. Look at the example for forwardInvocation: in the documentation for NSObject here: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html

Basically you override forwardInvocation and that is called when an object does not have a method that matches some given selector.

Bowes answered 15/11, 2012 at 4:21 Comment(1)
Thanks! I noticed besides - (void)forwardInvocation:(NSInvocation )anInvocation, I also need to implement the - (NSMethodSignature)methodSignatureForSelector:(SEL)selectorArachne

© 2022 - 2024 — McMap. All rights reserved.