So, I've been messing around with the objc-runtime again (surprise surprise), and I found an interesting block of code here:
const char *sel_getName(SEL sel) {
#if SUPPORT_IGNORED_SELECTOR_CONSTANT
if ((uintptr_t)sel == kIgnore) return "<ignored selector>";
#endif
return sel ? (const char *)sel : "<null selector>";
}
So, what this tells me is that a SEL
is equivalent to a C-string, in every mannerism. Doing a hex dump of the first 16 bytes of SEL that contains @selector(addObject:)
gives the following:
61 64 64 4F 62 6A 65 63 74 3A 00 00 00 00 00 00
Which is equal to the C-string addObject:
.
With that said, why does this code crash when I use the C-string as the selector?
SEL normalSEL = @selector(addObject:);
SEL cStringSEL = (SEL) "addObject:";
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1", @"2", nil];
[arr performSelector:normalSEL withObject:@"3"];
[arr performSelector:cStringSEL withObject:@"4"];
NSLog(@"%@", arr);
As far as I can tell, the contents of the selectors are the same, so why the crash on the second one with the following error message?
***
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM addObject:]: unrecognized selector sent to instance 0x101918720'***
C-strings are simply implemented as a char array which is terminated by a null character (aka 0 ). This last part of the definition is important: all C-strings are char arrays, but not all char arrays are c-strings. C-strings of this form are called “string literals“: const char * str = "This is a string literal.
In C++, the old C-style strings are often called C-Strings. Most C++ gurus would advise you to avoid C-Strings and just use std::string . And it is true that std::string is safer and easier to use than C-Strings.
In C programming, the collection of characters is stored in the form of arrays. This is also supported in C++ programming. Hence it's called C-strings. C-strings are arrays of type char terminated with null character, that is, \0 (ASCII value of null character is 0).
C-string (clothing), a specific type of thong, or a brand of women shorts.
Selectors are interned C strings and are compared by their address, not their contents. The string contents is only used for converting to/from an external string representation. Interning is done to improve performance--when the runtime is looking up the method implementation that matches a selector it can compare the selector pointers directly instead of dereferencing each pointer and comparing the characters.
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