我知道这两者有点相似,但两者之间肯定有任何内部差异,
[anObject performSelector:@selector(thisMethod:) withObject:passedObject];
相当于:
[anObject thisMethod:passedObject];
请告诉我在编译,内存等方面有什么区别。
我知道这两者有点相似,但两者之间肯定有任何内部差异,
[anObject performSelector:@selector(thisMethod:) withObject:passedObject];
相当于:
[anObject thisMethod:passedObject];
请告诉我在编译,内存等方面有什么区别。
方法族是针对特殊情况的performSelector
,Obj-C 中的绝大多数方法调用应该是直接的。一些区别:
间接:当使用performSelector
调用一个方法时,你有两个方法调用;和performSelector
目标方法。
参数是对象:当通过performSelector
所有参数调用时,必须作为对象传递,例如,如果调用采用 a 的方法,double
则该值必须NSNumber
在传递给之前包装为 an performSelector
。这些performSelector
方法在调用目标方法之前解包非对象参数。在直接调用中,不需要包装或展开。
只有两个参数:该performSelector
系列仅包含传递 0、1 或 2 个参数的变体,因此您不能使用它们来调用需要 3 个或更多参数的方法。
您可能将上述大部分内容视为负面因素,那么有什么好处呢?
动态选择器:该performSelector
系列允许您调用直到运行时才知道的方法,只需要知道其类型(因此您可以传递正确的参数并获得正确的结果);换句话说,选择器参数可能是type的表达式SEL
。当您希望将方法作为参数传递给另一个方法并调用它时,可能会使用此方法。但是,如果您使用动态选择器使用 ARC 进行编译,这并不重要,并且通常会产生编译器警告,因为不知道选择器 ARC 就无法知道参数的所有权属性。
延迟执行:该performSelector
系列包括在延迟后调用该方法的方法。
通常使用直接方法调用,只有当它不能给你你需要的东西时,你才需要考虑performSelector
家庭(或其更深奥的表亲)。
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).
该performSelector:
方法允许您发送直到运行时才确定的消息。有关更多信息,请阅读此内容。
如果您的应用程序想要使用reflection
,通过更改配置文件中的某些值,您想要调用不同的方法(不同的适配器)。或者基于对象类型,您想在运行时调用不同的方法。
如果您开发可定制的产品,这是一个强大的功能。
我喜欢在声明和实现自定义协议和委托模式时使用 [id performSelecter:selector withObject],这也是一个用例,我们应该使用 performSelector 而不是直接调用方法...