Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I get my category instance method even after calling it?

I'm trying to understand the Objective-C runtime a little bit better. Consider NSAttributedString.h which has a minimal interface followed by a more extensive category NSExtendedAttributedString.

Now consider the following code:

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithAttributedString:[[NSAttributedString alloc] initWithString:@"ABC"]];
NSLog(@"Result: %@", attributedString); 
NSLog(@"Exists? %@", [NSString stringWithUTF8String:sel_getName(method_getName(class_getInstanceMethod(NSAttributedString.class, @selector(initWithAttributedString:))))]);    
NSLog(@"Exists? %@", [NSString stringWithUTF8String:sel_getName(method_getName(class_getInstanceMethod(NSAttributedString.class, @selector(string))))]);

// Produces this output
2013-04-19 10:17:35.364 TestApp[53300:c07] Result: ABC{
}
2013-04-19 10:17:35.364 TestApp[53300:c07] Exists? <null selector>
2013-04-19 10:17:35.365 TestApp[53300:c07] Exists? string

We find the instance method that is part of the canonical interface, but not the one in the category. How can this happen and yet it can be successfully called? Is there a way to introspect and find the category method?

like image 566
Ben Flynn Avatar asked Oct 21 '22 11:10

Ben Flynn


1 Answers

What happens in this case is that you assume attributedString to be of type NSAttributedString, which is not the case:

NSLog(@"Class: %@", [attributedString class]);

// Produces this output
2013-04-19 19:50:21.955 TestApp[1611:303] Class: NSConcreteAttributedString

If you change NSAttributedString.class in your code to [attributedString class] it will work as expected.

like image 168
proxi Avatar answered Jan 02 '23 21:01

proxi