IOS开发入门之iOS 多线程
凌雪 2018-11-09 来源 :网络 阅读 746 评论 0

摘要:本文将带你了解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频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程