Recently, I'm studying the runtime in Objective-C.
I created a class named TO
:
@interface TO : NSObject
@end
#import "TO.h"
@implementation TO
- (id)forwardingTargetForSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return nil;
}
- (BOOL)respondsToSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return NO;
}
+ (BOOL)resolveClassMethod:(SEL)sel {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(sel));
return NO;
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(sel));
return NO;
}
+ (IMP)instanceMethodForSelector:(SEL)aSelector {
NSLog(@"%@ sel: %@", NSStringFromSelector(_cmd), NSStringFromSelector(aSelector));
return nil;
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog(@"%@", NSStringFromSelector(_cmd));
}
@end
Then, I call an unrecongnized selector somewhere:
TO *to = [TO new];
id res = [(NSString *)to uppercaseString];
Subsequently, I got the following output:
2015-12-22 22:27:04.319 OCDemo[81920:7728539] resolveInstanceMethod: sel: uppercaseString
2015-12-22 22:27:04.320 OCDemo[81920:7728539] forwardingTargetForSelector: sel: uppercaseString
2015-12-22 22:27:04.320 OCDemo[81920:7728539] resolveInstanceMethod: sel: uppercaseString
2015-12-22 22:27:04.320 OCDemo[81920:7728539] -[TO uppercaseString]: unrecognized selector sent to instance 0x7fdd3ad120a0
2015-12-22 22:27:04.322 OCDemo[81920:7728539] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TO uppercaseString]: unrecognized selector sent to instance 0x7fdd3ad120a0'
As we see, resolveInstanceMethod:
was called twice.
However,if I call -[description]
firstly:
TO *to = [TO new];
[to description];
id res = [(NSString *)to uppercaseString];
Then, the output would be:
2015-12-22 22:58:50.458 OCDemo[82137:7813436] resolveInstanceMethod: sel: uppercaseString
2015-12-22 22:58:50.459 OCDemo[82137:7813436] forwardingTargetForSelector: sel: uppercaseString
2015-12-22 22:58:50.459 OCDemo[82137:7813436] -[TO uppercaseString]: unrecognized selector sent to instance 0x7f9bcad59960
2015-12-22 22:58:50.461 OCDemo[82137:7813436] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TO uppercaseString]: unrecognized selector sent to instance 0x7f9bcad59960'
This time resolveInstanceMethod:
was called only once.
Could someone please explain this?