2

我知道这两者有点相似,但两者之间肯定有任何内部差异,

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

相当于:

[anObject thisMethod:passedObject];

请告诉我在编译,内存等方面有什么区别。

4

5 回答 5

7

方法族是针对特殊情况的performSelector,Obj-C 中的绝大多数方法调用应该是直接的。一些区别:

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

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

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

您可能将上述大部分内容视为负面因素,那么有什么好处呢?

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

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

通常使用直接方法调用,只有当它不能给你你需要的东西时,你才需要考虑performSelector家庭(或其更深奥的表亲)。

于 2013-03-06T03:48:41.273 回答
3

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

一般来说,这种间接性——通常称为反射,但更准确地称为元编程——是应该避免的,因为它将应该是编译时可检测到的故障转移到运行时故障。

Such dynamism is only needed when the name of the selector -- the name of the method -- being called cannot be determined at compile time. It should not be used for @optional methods in protocols nor should it be used during delegation (in both cases, respondsToSelector: + a direct method call are a far better pattern to employ).

于 2013-03-06T03:56:18.980 回答
1

performSelector:方法允许您发送直到运行时才确定的消息。有关更多信息,请阅读此内容。

于 2013-03-06T03:15:58.560 回答
0

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

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

于 2013-03-06T03:12:50.643 回答
-1

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

于 2013-03-06T03:33:43.873 回答