performSelector或直接

时间:2013-03-06 03:05:00

标签: ios objective-c cocoa performselector

据我所知,这两者有点相似,但两者之间必然存在内部差异,

[anObject performSelector:@selector(thisMethod:) withObject:passedObject];

相当于:

[anObject thisMethod:passedObject];

请告诉我编译,记忆等方面的差异。

5 个答案:

答案 0 :(得分:7)

performSelector系列方法适用于特殊情况,Obj-C中的绝大多数方法调用都应该是直接的。一些差异:

间接:使用performSelector调用方法时,您有两个方法调用; performSelector和目标方法。

参数是对象:当通过performSelector调用时,所有参数必须作为对象传递,例如如果调用一个采用double的方法,则该值必须在传递给NSNumber之前包装为performSelectorperformSelector方法在调用目标方法之前解包非对象参数。在直接调用中,不需要包装或展开。

只有两个参数: performSelector系列只包含传递0,1或2个参数的变体,因此您不能使用它们来调用带有3个或更多参数的方法。

您可能会将上述大部分内容视为否定因素,那么有什么好处?

动态选择器: performSelector系列允许您调用直到运行时才知道的方法,只需知道其类型(因此您可以传递正确的论据,得到正确的结果);换句话说,selector参数可以是SEL类型的表达式。当您希望将方法作为参数传递给另一个方法并调用它时,可以使用此方法。 但是如果使用动态选择器使用ARC进行编译是非常重要的,并且通常会产生编译器警告,因为不知道选择器ARC无法知道参数的所有权属性。

延迟执行: performSelector系列包括在延迟后调用该方法的方法。

一般情况下,使用直接方法调用,只有在不能满足您要求的情况下才需要考虑performSelector系列(或者更为深奥的堂兄弟)。

答案 1 :(得分:3)

performSelector:withObject:比直接调用方法稍慢。间接也意味着编译器无法进行正确的类型检查。启用ARC后,您还会遇到编译器会抱怨的问题,因为无法准确确定内存管理策略可能是什么。

一般来说,这种间接 - 通常称为反射,但更准确地称为元编程 - 应该完全避免,因为它移动应该编译的内容时间可检测的运行时故障失败。

仅当选择器的名称 - 方法的名称 - 在编译时无法确定时,才需要这种动态。它不应该用于协议中的@optional方法,也不应该在委派期间使用(在这两种情况下,respondsToSelector: +直接方法调用都是一种更好的模式。

答案 2 :(得分:1)

performSelector:方法允许您发送在运行时之前未确定的消息。有关详情,请阅读this.

答案 3 :(得分:0)

如果您的应用想要使用reflection,那么通过更改配置文件中的某些值,您需要调用其他方法(不同的适配器)。或者基于对象类型,您希望在运行时调用不同的方法。

如果您开发可自定义的产品,这是一个强大的功能。

答案 4 :(得分:-1)

我喜欢在声明和实现自定义协议时使用[id performSelecter:selector withObject],并委托模式,它也是一个用例,我们应该使用performselector而不是直接调用方法......