微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

非字母数字字符可以用作选择器吗?

如何解决非字母数字字符可以用作选择器吗?

| 以下代码可以编译并正常运行(请注意
sel_registerName(\"+\")
):
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>

@interface Integer : NSObject
{
    NSInteger   intValue;
}

@property (assign) NSInteger intValue;

@end

@implementation Integer

@synthesize intValue;

- (id) plus:(Integer*)anInteger
{
    Integer* outInt = [Integer new];
    [outInt setIntValue: intValue + [anInteger intValue]];
    return outInt;
}

@end


int main (int argc,char const *argv[])
{
    id pool = [[NSAutoreleasePool alloc] init];

    SEL plusSel = sel_registerName(\"+\");
    Method m = class_getInstanceMethod([Integer class],@selector(plus:));
    class_addMethod([Integer class],plusSel,method_getImplementation(m),method_getTypeEncoding(m));

    Integer* i4 = [Integer new];
    Integer* i20 = [Integer new];
    [i4 setIntValue: 4];
    [i20 setIntValue: 20];

    Integer* res = objc_msgSend(i4,i20);

    NSLog(@\"%d + %d = %d\",[i4 intValue],[i20 intValue],[res intValue]);
    //  >> 4 + 20 = 24

    [pool drain];
    return 0;
}
除了\“ yuck \\”之外,还有其他理由对此采取谨慎态度吗?     

解决方法

        ObjC运行时的API不太可能更改,但是调用sel_registerName(\“ + \”)的有效性可能会改变。我在ObjC运行时中花了很多时间,即使经过多次更新,也没有遇到任何问题。话虽这么说,我不会以此为基础的数百万美元的业务永远持续下去。     ,        当前,Objective-C运行时库不对您尝试注册的字符串的内容执行任何检查,并且开发团队不太可能更改该行为。如果它是一个非空的C字符串,如果您始终使用
objc_msgSend
发送该选择器的消息,并且不尝试执行ѭ3like之类的操作(这将导致编译错误),则没有理由害怕。 已注册的Objective-C选择器实际上是运行时系统在内部存储的C字符串。运行时系统保留一个指向C字符串的指针表,即所谓的SEL集。当您调用
sel_registerName
时,ObjC运行时系统将为您的字符串以及SEL集中存储的每个C字符串调用
strcmp
。如果SEL集中的任何C字符串等于您要注册的C字符串,则该函数将返回该集中相应C字符串的地址。否则,系统将复制您的字符串(带有
strdup
),将结果指针存储在SEL集中并返回它。这个新的指针成为一个新的唯一选择器。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。