Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't we use C-strings as SELs?

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' ***

like image 623
Richard J. Ross III Avatar asked May 28 '12 18:05

Richard J. Ross III


People also ask

Are strings and C strings the same?

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.

Should you use strings in C++?

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.

Is string object in C?

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).

What is a C string?

C-string (clothing), a specific type of thong, or a brand of women shorts.


1 Answers

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.

like image 89
rpetrich Avatar answered Oct 01 '22 03:10

rpetrich