为什么我们不能将C字符串用作SEL? [英] Why can't we use C-strings as SELs?

查看:106
本文介绍了为什么我们不能将C字符串用作SEL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我又在弄乱objc-runtime(感到惊讶),并且发现了一个有趣的代码块

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>";
}

所以,这告诉我,在每种方式下,SEL均等效于C字符串.对包含@selector(addObject:)的SEL的前16个字节进行十六进制转储会得到以下结果:

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

61 64 64 4F 62 6A 65 63 74 3A 00 00 00 00 00 00

等于C字符串addObject:.

话虽如此,当我使用C字符串作为选择器时,为什么此代码会崩溃?

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?

***由于未捕获的异常"NSInvalidArgumentException"而终止应用程序, 原因:'-[__ NSArrayM addObject:]:无法识别的选择器已发送到实例 0x101918720'***

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM addObject:]: unrecognized selector sent to instance 0x101918720' ***

推荐答案

选择器是内在的C字符串,并通过其地址而不是其内容进行比较.字符串内容仅用于与外部字符串表示形式之间的转换.已经进行了实习以提高性能-当运行时查找与选择器匹配的方法实现时,它可以直接比较选择器指针,而不用取消引用每个指针并比较字符.

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.

这篇关于为什么我们不能将C字符串用作SEL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆