NSInvocation用来呈现objective-C静态消息,即将动作转换为一个对象。NSInvocation对象用来在对象或者应用程序间存储以及转发消息。主要应用于NSTimee对象或者是分布式对象系统中。一个NSInvocation对象包含了所有的OC消息的成分:目标、selector、参数以及返回值。每一个参数能够直接设定,而且当一个NSInvocation对象调度时返回值是自动设定的。同时一个NSInvocation对象能够重复的调度不同的目标,它的参数可以根据不同的参数改变调度,而且它的selector能够改变为另外一个获得同样签名(即参数和返回值)的方法。
注意:NSInvocation遵守NSCoding协议,但是仅支持NSPortCoder编码,不支持归档型操作。完成一个NSInvocation对象的任务步骤:
使用类方法 + invocationWithMethodSignature:对一个给定的方法进行签名,返回构建了消息的NSInvocation对象。实例有:
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(writeData:toPath:)]];
使用- (void)setArgument:(void *)buffer atIndex:(NSInteger)index来设定NSInvocation中方法中的参数。注意的是:index为0和1不能使用,因为他们作为隐藏的参数self和_cmd;我们只能使用大于1的数来作为传入的index值。具体的设置属性实例如下:
[writeInvocation setTarget:self];
[writeInvocation setSelector:@selector(writeData:toPath:)];
[writeInvocation setArgument:&data atIndex:2];//data为传入数据的指针,并且其index为2;
[writeInvocation setArgument:&cache atIndex:3];//cache为传入数据的指针,并且其index为3
有了NSInvocation,那就需要对其进行封装了。NSInvocationOperation作为NSOperation类的一个具体类,它能够完成封装的单个任务的操作。该任务具体为一个函数的调用,实体为一个NSInvocation的对象或者是入口函数的地址。我们从该类的初始化方法可以看到一种是使用NSInvocation对象,即- (id)initWithInvocation:(NSInvocation *)inv,还有一种是直接指定一个函数的入口地址,即- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg。第一种方法就没有什么可说的,第二种直接指定一个函数的入口地址,因为函数可能需要传入参数,也可能返回参数,那么如何实现呢?使用arg参数传递给selector。如果需要传参数给那么就给arg,如果不需要传入参数,就将arg为nil。
代码例子如下:
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithInvocation:invoction];
而对于NSBlockOperation作为NSOperation的另外一个具体的子类,使用起来相对来说比较简单。NSBlockOperation对象的初始化方法也只有一种,即+ (id)blockOperationWithBlock:(void (^)(void))block,其中block为没有任何参数也没有返回值的函数地址。具体代码为:
NSBlockOperation **operation = [[NSBlockOperation alloc] initWithBlock:block];//注意这里的block为没有任何参数也没有返回值的函数地址。
知道了NSOperation的子类,现在就可以采用NSOperationQueue来使用多线程了!
NSOperationQueue作为操作队列,只需要在初始化之后,直接添加操作就行。因为其线程化层次较高,所以安全性也比较高。如果在多线程中只有一个NSOperationQueue对象,就不需要考虑线程同步的问题。具体例程为:
NSOperationQueue *operationQueue=[[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];//operation可为NSBlockOperation对象,也可谓NSInvocationOperation对象
===============================================我是分割线==========================
前面已经完成采用操作队列来完成任务的操作。对于IOS4.0之后,操作队列可以认为是多线程(线程数>=3)操作,而在IOS4.0之前只能认为是采用两个线程完成任务(一个是主线程,第二个线程用来挨个执行操作队列中的任务)。