在查看的源代码时,我遇到了两行代码,我对此感到困惑:
//[obj performSelector:normalSelector withObject:command];
objc_msgSend(obj,normalSelector,command);从苹果的文档来看,这两种方法似乎并没有太大的区别。
id objc_msgSend(id theReceiver,SEL theSelector,.)向类的实例发送带有简单返回值的消息。
(id)performSelector:(SEL)aSelectorwithObject:(id)anObject以对象作为参数向接收方发送消息。(必填)
这两种方法到底有什么区别?在上面的例子中,两者都是将带有对象的消息作为参数发送给接收对象。
发布于 2012-09-03 03:31:41
您在问两个“方法”之间的区别,但实际上只有一个方法是一个方法。objc_msgSend函数是一个函数。不是什么方法。
objc_msgSend函数是在对目标C中的任何对象调用任何方法时实际调用的函数。例如,以下两个函数基本上是等价的:
// This is what the compiler generates
objc_msgSend(obj, @selector(sel:), param);
// This is what you write
[obj sel:param];
// You can check the assembly output, they are *almost* identical!这里的主要区别是,objc_msgSend没有得到编译器检查的类型--或者至少它的参数没有根据选择器的参数类型进行类型检查。因此,以下内容大致相等:
[obj performSelector:normalSelector withObject:command];
objc_msgSend(obj, @selector(performSelector:withObject:),
normalSelector, command);但是,这有点浪费,因为performSelector:withObject:所做的就是调用objc_msgSend。
然而,:正如上面所提到的,您应该远离obc_msgSend,因为它不是类型安全的。apache所做的只是删除一个方法调用,这在大多数情况下只会给您带来很小的性能好处。
发布于 2012-09-03 03:26:14
注释掉的行是正确的,objc_msgSend()行是不正确的,因为它需要显式类型(varargs不兼容某些平台上的非varargs函数调用)。
实际上,他们也在做同样的事情。实际上,方法调用版本只是objc_msgSend()的包装器。
https://stackoverflow.com/questions/12241596
复制相似问题