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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With