在您的代码中调用objc_msgSend()的危险是什么?
解决方法 原因1:糟糕的风格 – 它是多余的和不可读的。当遇到Objective-C消息传递表达式时,编译器会自动生成对objc_msgSend()(或其某些变体)的调用。如果您知道在编译时发送的类和选择器,则无需编写
ID obj = objc_msgSend(objc_msgSend([NSObject class],@selector(alloc)),@selector(init));
代替
ID obj = [[NSObject alloc] init];
即使您不知道该类或选择器(甚至两者),它仍然更安全(至少编译器有机会警告您,如果您正在做一些可能令人讨厌/错误的事情),以获得正确类型的函数指针实现本身并使用该函数指针:
const char *(*fptr)(Nsstring *,SEL) = [Nsstring instanceMethodForSelector:@selector(UTF8String)];const char *cstr = fptr(@"Foo");
当一个方法的参数的类型对默认的促销活动很敏感时,尤其如此,如果是这样,那么你不想通过它们传递参数objc_msgSend(),因为你的程序会很快地调用未定义的行为。
原因#2:危险且容易出错。
注意#1中的“或其变体”部分。并非所有消息发送都使用objc_msgSend()函数本身。由于ABI中的复杂性和要求(特别是在功能的调用惯例中),有单独的函数用于返回,例如浮点值或结构。例如,在执行某种搜索(子串等)的方法的情况下,并且返回NSRange结构,根据该平台,可能需要使用信使函数的结构返回版本:
NSRange retval;objc_msgSend_stret(&retval,@"Foobar",@selector(rangeOfString:),@"bar");
如果你这样做错了(例如你使用不正确的信使功能,你将指针混合到返回值和自我等等),你的程序可能会出现错误和/或崩溃的行为。 (并且你最有可能会错了,因为它不是那么简单 – 并不是所有返回结构体的方法都使用这个变体,因为小结构将适合一个或两个处理器寄存器,因此无需使用堆栈作为返回值,这就是为什么 – 除非你是一个硬核的ABI黑客 – 你更希望让编译器做它的工作,或者有龙。)
总结以上是内存溢出为你收集整理的objective-c – 为什么不应该在Objective C中使用objc_msgSend()?全部内容,希望文章能够帮你解决objective-c – 为什么不应该在Objective C中使用objc_msgSend()?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)