摘要:本文将带你了解IOS开发入门iOS 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用,希望本文对大家学IOS有所帮助。
本文将带你了解IOS开发入门iOS 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用,希望本文对大家学IOS有所帮助。
iOS 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用。
本篇文章主要介绍下多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用,列举几个简单的例子。
默认情况下,NSOperation并不具备封装操作的能力,必须使用它的子类,使用NSOperation子类的方式有3种:
1>自定义子类继承NSOperation,实现内部相应的方法
2> NSBlockOperation
3>NSInvocationOperation
这讲先介绍如何用NSOperation封装一个操作,后面再结合NSOperationQueue来使用。
1.首先介绍自定义NSOperation:
NSOperation是没法直接使用的,它只是提供了一个工作的基本逻辑,具体实现还是需要你通过定义自己的NSOperation子类来获得。
[objc]view plaincopy
#import
@protocolNSDefineOprationDelegate
-(void)handleDelegate;
@end
@interfaceNSDefineOpration:NSOperation
@property(nonatomic,assign)iddelegate;
-(id)initWithDelegate:(id)delegate;
@end
实现文件里:
[objc]view plaincopy
#import"NSDefineOpration.h"
@implementationNSDefineOpration
-(id)initWithDelegate:(id)delegate
{
if(self=[superinit])
{
self.delegate=delegate;
}
returnself;
}
-(void)main
{
@autoreleasepool{
//dosomething
sleep(15);
NSLog(@"op1........handle......onthreadnum:%@",[NSThreadcurrentThread]);
if([self.delegaterespondsToSelector:@selector(handleDelegate)])
{
[self.delegateperformSelector:@selector(handleDelegate)withObject:nil];
}
}
}
@end 这里的sleep(15)主要用来做一些延时的操作,比如网络下载等。
调用:
[objc]view plaincopy
-(void)oprationTest
{
NSDefineOpration*op1=[[NSDefineOprationalloc]initWithDelegate:self];
op1.completionBlock=^(){
NSLog(@"op1........OK!!");
};
[op1start];
}
执行结果:
[objc]view plaincopy
2014-03-2216:49:44.367Operation[17353:60b]op1........handle......onthreadnum:{name=(null),num=1}
2014-03-2216:49:49.373Operation[17353:60b]op1.....callback.....onthreadnum:{name=(null),num=1}
2014-03-2216:49:49.377Operation[17353:1807]op1........OK!!
从执行结果可以看出,因为在实现的main函数里没有使用异步线程处理,导致直接阻塞了主线程1,所以使用这种方式一定注意main函数里操作时间过长导致主线程阻塞问题。耗时比较长的都放到其他线程里处理。
2.接下来介绍NSBlockOperation
第一种使用NSBlockOperation的方式:
[objc]view plaincopy
NSLog(@"blockstart");
NSBlockOperation*bop2=[NSBlockOperationblockOperationWithBlock:^{
sleep(15);
NSLog(@"bop2.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bop2setCompletionBlock:^{
NSLog(@"bop2........OK!!");
}];
[bop2start];
* 第2行初始化了一个NSBlockOperation对象,它是用一个Block来封装需要执行的操作
*第9行调用了start方法,紧接着会马上执行Block中的内容
看下执行结果:
[objc]view plaincopy
2014-03-2216:57:51.903Operation[17374:60b]blockstart
2014-03-2216:58:06.908Operation[17374:60b]bop2.....handle.....onthreadnum{name=(null),num=1}
2014-03-2216:58:06.912Operation[17374:360b]bop2........OK!!
* 这里还是在当前线程同步执行操作,并没有异步执行,阻塞主线程。
第二种使用NSBlockOperation的方式:
[objc]view plaincopy
-(void)blockOprationTest
{
NSLog(@"blockstart");
NSBlockOperation*op2=[[NSBlockOperationalloc]init];
[op2addExecutionBlock:^{
sleep(10);
NSLog(@"op2.....handle.....on10hreadnum%@",[NSThreadcurrentThread]);
}];
[op2addExecutionBlock:^{
sleep(6);
NSLog(@"op2.....handle.....on6threadnum%@",[NSThreadcurrentThread]);
}];
[op2addExecutionBlock:^{
sleep(4);
NSLog(@"op2.....handle.....on4threadnum%@",[NSThreadcurrentThread]);
}];
[op2addExecutionBlock:^{
sleep(8);
NSLog(@"op2.....handle.....on8threadnum%@",[NSThreadcurrentThread]);
}];
[op2addExecutionBlock:^{
sleep(1);
NSLog(@"op2.....handle.....on1threadnum%@",[NSThreadcurrentThread]);
}];
[op2setCompletionBlock:^{
NSLog(@"op2........OK!!");
}];
[op2start];
//bop2
NSBlockOperation*bop2=[NSBlockOperationblockOperationWithBlock:^{
sleep(15);
NSLog(@"bop2.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bop2setCompletionBlock:^{
NSLog(@"bop2........OK!!");
}];
[bop2start];
}
执行结果:
[objc]view plaincopy
2014-03-2217:02:56.027Operation[17396:60b]blockstart
2014-03-2217:03:02.032Operation[17396:1803]op2.....handle.....on6threadnum{name=(null),num=2}
2014-03-2217:03:06.032Operation[17396:60b]op2.....handle.....on10hreadnum{name=(null),num=1}
2014-03-2217:03:06.035Operation[17396:1803]op2.....handle.....on4threadnum{name=(null),num=2}
2014-03-2217:03:07.038Operation[17396:1803]op2.....handle.....on1threadnum{name=(null),num=2}
2014-03-2217:03:14.035Operation[17396:60b]op2.....handle.....on8threadnum{name=(null),num=1}
2014-03-2217:03:14.037Operation[17396:1807]op2........OK!!
2014-03-2217:03:29.038Operation[17396:60b]bop2.....handle.....onthreadnum{name=(null),num=1}
2014-03-2217:03:29.041Operation[17396:180b]bop2........OK!!
分析下结果:
首先看到了有1和2两个线程,线程2在56秒的时候开始执行6秒的操作,接下来执行4,1秒结束时间为07秒。线程1在56的时候开始执行10秒的操作,接下来执行8秒,结束时间为14秒。最后执行Bop2的15秒操作至29秒。时间看起来没有问题。为什么会启用2个线程而不是3个或者更多?
3.接下来介绍NSInvocationOperation
[objc]view plaincopy
-(void)invocationOperation
{
NSInvocationOperation*op3=[[NSInvocationOperationalloc]initWithTarget:(id)selfselector:@selector(handleInvoOpDelegate)object:nil];
[op3setCompletionBlock:^{
NSLog(@"op3........OK!!");
}];
[op3start];
}
selector函数:
[objc]view plaincopy
-(void)handleInvoOpD
{
sleep(5);
NSLog(@"op3.....handle.....onthreadnum:%@",[NSThreadcurrentThread]);
}
执行结果:
[objc]view plaincopy
2014-03-2217:11:13.050Operation[17421:60b]op3.....handle.....onthreadnum:{name=(null),num=1}
2014-03-2217:11:13.055Operation[17421:1803]op3........OK!!
NSInvocationOperation比较简单,就是继承了NSOperation,区别就是它是基于一个对象和selector来创建操作,可以直接使用而不需继承来实现自己的操作处理。
4.最后介绍下NSOperationQueue
把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。队列里可以加入很多个NSOperation,可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。
实现demo:
[objc]view plaincopy
-(void)handleOpqueue
{
NSOperationQueue*qu=[[NSOperationQueuealloc]init];
NSBlockOperation*bkOp1=[NSBlockOperationblockOperationWithBlock:^{
sleep(10);
NSLog(@"bkOp1.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bkOp1setCompletionBlock:^{
NSLog(@"bkOp1........OK!!");
}];
NSBlockOperation*bkOp2=[NSBlockOperationblockOperationWithBlock:^{
sleep(2);
NSLog(@"bkOp2.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bkOp2setCompletionBlock:^{
NSLog(@"bkOp2........OK!!");
}];
NSBlockOperation*bkOp3=[NSBlockOperationblockOperationWithBlock:^{
sleep(1);
NSLog(@"bkOp3.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bkOp3setCompletionBlock:^{
NSLog(@"bkOp3........OK!!");
}];
NSBlockOperation*bkOp4=[NSBlockOperationblockOperationWithBlock:^{
sleep(10);
NSLog(@"bkOp4.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bkOp4setCompletionBlock:^{
NSLog(@"bkOp4........OK!!");
}];
NSBlockOperation*bkOp5=[NSBlockOperationblockOperationWithBlock:^{
sleep(5);
NSLog(@"bkOp5.....handle.....onthreadnum%@",[NSThreadcurrentThread]);
}];
[bkOp5setQueuePriority:NSOperationQueuePriorityHigh];
[bkOp5setCompletionBlock:^{
NSLog(@"bkOp5........OK!!");
}];
NSInvocationOperation*invoOp6=[[NSInvocationOperationalloc]initWithTarget:(id)selfselector:@selector(handleInvoOp)object:nil];
[invoOp6setCompletionBlock:^{
NSLog(@"invoOp6........OK!!");
}];
[invoOp6setQueuePriority:NSOperationQueuePriorityHigh];
[qusetMaxConcurrentOperationCount:2];
[quaddOperation:bkOp3];
[quaddOperation:bkOp2];
[quaddOperation:bkOp1];
[quaddOperation:bkOp4];
[quaddOperation:bkOp5];
[quaddOperation:invoOp6];
}
先看下执行结果:
[objc]view plaincopy
2014-03-2217:18:36.634Operation[17439:1803]bkOp3.....handle.....onthreadnum{name=(null),num=2}
2014-03-2217:18:36.638Operation[17439:1803]bkOp3........OK!!
2014-03-2217:18:37.635Operation[17439:3607]bkOp2.....handle.....onthreadnum{name=(null),num=3}
2014-03-2217:18:37.637Operation[17439:3607]bkOp2........OK!!
2014-03-2217:18:41.640Operation[17439:3d07]bkOp5.....handle.....onthreadnum{name=(null),num=4}
2014-03-2217:18:41.642Operation[17439:3d07]bkOp5........OK!!
2014-03-2217:18:42.639Operation[17439:1803]invoOp6.....handle.....onthreadnum:{name=(null),num=2}
2014-03-2217:18:42.643Operation[17439:1803]invoOp6........OK!!
2014-03-2217:18:51.644Operation[17439:3607]bkOp1.....handle.....onthreadnum{name=(null),num=3}
2014-03-2217:18:51.646Operation[17439:3607]bkOp1........OK!!
2014-03-2217:18:52.645Operation[17439:3d07]bkOp4.....handle.....onthreadnum{name=(null),num=4}
2014-03-2217:18:52.647Operation[17439:3d07]bkOp4........OK!!
从结果可以看出,NSOperationQueue在2,3,4这3个线程里去处理NSOperation,而不包括主线程1。此外,在设置了bkop5以及invOp6的优先级为高时,他们会优先执行,当然这个优先时相对,是相对正在排队的,不包括已经正在执行的。
总结:NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue都比较简单,NSOperation、NSBlockOperation、NSInvocationOperation单个都是表示一种操作,而NSOperationQueue是一个可以包含多个NSOperation的队列,可以自己在多个线程处理,只要加入队列之后,我们就不用去操作,直到Callback或者完成。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号