objective-c – 为什么不应该在Objective C中使用objc_msgSend()?

objective-c – 为什么不应该在Objective C中使用objc_msgSend()?,第1张

概述Apple的Objective C Runtime Guide指出,您不应该在自己的代码中使用objc_msgSend(),建议使用methodForSelector:代替。但是,它没有提供任何理由。 在您的代码中调用objc_msgSend()的危险是什么? 原因1:糟糕的风格 – 它是多余的和不可读的。 当遇到Objective-C消息传递表达式时,编译器会自动生成对objc_msgSend( Apple的Objective C Runtime GuIDe指出,您不应该在自己的代码中使用objc_msgSend(),建议使用methodForSelector:代替。但是,它没有提供任何理由。

在您的代码中调用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()?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1037832.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存