performselector
原文链接:http://www.cnblogs.com/agger0207/p/4426131.html
performSelector调用和直接调用的区别
今天在准备出笔试题的过程中随便搜了一下其他的笔试题,看到其中一个就是关于performSelector与直接调用的区别。
个人感觉这其实是一个陷阱题,因为大部分应用场景下,用哪一种都可以,可以说是没有区别的,但其实又有一些细节上的区别。
比如说,假如有如下代码:
- (void)doTest { Student* student = [[Student alloc] init]; [student performSelector:@selector(doSomething)]; [student doSomething]; }
具体执行过程中的区别道理是什么呢?
还是先看官方文档对performSelector的描述:
- (id)performSelector:(SEL)aSelector |
||
Description |
Sends a specified message to the receiver and returns the result of the message. (required) |
|
The performSelector: method is equivalent to sending an aSelector message directly to the receiver. For example, all three of the following messages do the same thing: id myclone = [anObject copy]; id myClone = [anObject performSelector:@selector(copy)]; id myClone = [anObject performSelector:sel_getUid("copy")]; However, the performSelector: method allows you to send messages that aren’t determined until runtime。 A variable selector can be passed as the argument:
|
核心的就那么几句:
1 执行的效果其实和发送消息是等价的;
2 performSelector允许发送未在运行时确定的消息;也就是说,只要这个消息能够被转发到正确的接收者,能够被最后的接收者识别,都是可以正确运行的。否则,就会在运行时报错“unrecognized selector sent to instance”.
具体来说:假如上面的Student的定义和实现如下:
@interface Student : NSObject - (void)doSomething; @end @implementation Student - (void)doSomething { NSLog(@"doSomething"); } @end
那么这两者基本上是等价的;但是,假如doSomething是一个私有的方法呢? 可以试着将这个方法从头文件中删除如下:
@interface Student : NSObject @end
这个时候[student doSomething];就会在编译时候报错啦!
而对于performSelector呢,仅仅当编译警告选项“Undeclared Selector”打开的时候才会有编译警告。
另外,即使这个方法并没有实现,也就是说从.m文件中删除这个方法,编译是可以通过的,但是运行时会Crash,报的错误就是刚才的“unrecognized selector sent to instance”.
我自己由于是从C++程序员转过来的,所以其实更喜欢[student doSomething]这种方法,一旦有问题的时候,在编译期间就很容易发现啦!
但Obejct-C的动态特性是允许在运行时向某个类添加方法的,这个时候就一定需要使用performSelector了。那么为了避免运行时出现错误,在使用performSelector之前一定要使用如下的检查方法来进行判断。
- (BOOL)respondsToSelector:(SEL)aSelector;
The End.
相关阅读
typedef和define都是替一个对象取一个别名,以此增强程序的可读性,区别如下:(1)原理不同#define是C语言中定义的语法,是预处理指令,在预处
windows RT开发笔记:WinRT DLL及其调用研究
一. 几个概念:WinRT :Windows Runtime, windows运行时。创建Windows运行时(WinRT)是为了在Windows上给用户提供一种流畅且安全的应用
推荐几款可以直接在手机上编程的app(包含Java、C、Pyt
这里介绍几款可以在手机上编程的app,分别是: 1.java和Android:AIDE集成开发环境。 2.C语言:c语言编译器、C4droid。 3.python:QPyth
Java中notify和notifyAll的区别 - 何时以及如何使用
Java notify vs notifyAll notify和notifyAll方法之间有什么区别是棘手的Java问题之一! Condition 是个什么玩
荣耀新发布的智能语音4K盒子-荣耀盒子voice,与上一代荣耀盒子、华为盒子和秘盒有什么区别呢?该如何根据自己的需求购买盒子呢?一、接