上一篇我们有分析runtime的大概实现过程,我们知道了objc_msgsend这个东西。它说的就是c语言的消息分发底层的大概实现。那么我们在iOS开发的过程中,实际会使用到的最直接的基于runtime机制的消息方法不就是performselector方法嘛!今天,我们就来分析一下这个东西:(同样成果是基于自己实践与看别人的博客的基础,所以也唠叨一下,希望各位可以多看看别人的博客哦,或者自己写写)
SEL:这个是一个类似c++函数指针的东西,它可以与字符串相互转换。它对应相应的方法地址,找到地址就可以调用方法了;
调用@selector,就要用到我们的perform selector了。
线程在运行过程中,可能需要与其它线程进行通信。我们可以使用NSObject中的一些方法:
在主线程执行:(比如UI主线程)
performSelectorOnMainThread: withObject: waitUntilDone:
performSelectorOnMainThread: WithObject: waitUntilDone: modes:
waitUntilDoone控制同步和异步。NO为异步;YES为同步。
在指定线程内执行:
performSelector:OnThread: withObject: waitUntilDone:
performSelector: OnThread: WithObject: waitUntilDone: modes:
在当前线程执行:performSelector:withObject:afterDelay:
performSelector:withObject:afterDelay:inModes:
取消发送给当前线程的某个消息
cancelPreviousPerformRequestsWithTarget:
cancelPreviousPerformRequestsWithTarget:selector:object:
上面的这些都是出自NSRunloop.h;还有一套NSObject.h
-(id)performSelector:(SEL)aSelector;
-(id)performSelector:(SEL)aSelector withObject:(id)object;
-(id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
我们经常用到的阳光是继承自NSObject的类;
但是,你大概注意到了,使用这个的话有个缺陷,它的参数个数一般不多于2个。好,这个时候,我们就注意到iOS还有另外一套东西:NSInvocation;
这个就没什么好讲的了,直接上代码,看了就明白了:
.h文件
#import <Foundation/Foundation.h>
/**
* 这是一个Category,创建category的方法是source里的Object-C file,输入的名字就是+后面的名字。
*/
@interface NSObject (performSelector)
-(id)performSelector:(SEL)aSelector withObjects:(NSArray *)object;
@end
#import "NSObject+performSelector.h"
@implementation NSObject (performSelector)
-(id)performSelector:(SEL)aSelector withObjects:(NSArray *)object
{