iOS自学之NSOperation、NSOperationQueue、Background
iOS中多线程编程主要分为NSThread、NSOperation和GCD,今天主要记录下自己在学习NSOperation中的点滴~如有不对的地方帮忙指出下,PS:人生第一次写blog,各位看官请轻虐,谢啦~
NSOperation是abstract类,不能直接使用,可以使用CocoTouch提供的NSBlockOperaion和NSInvocationOperation,也可以自己实现subclass。NSOperation可以理解为一个独立的任务,没有调度功能,真正利用NSOperation实现多线程的关键是NSOperationQueue,当NSOperation 添加到NSOperationQueue后,NSOperationQueue就会给队列中的NSOperation分配线程并调度。
1、NSOperationQueue为队列中的NSOperation分配不同的线程,测试代码如下:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"main Thread is %p",[NSThread mainThread]);
[self testOperationWithQueue];
}
- (void)testOperationWithQueue
{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"blockOperation1:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"blockOperation2:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"blockOperation3:current Thread is %p",[NSThread currentThread]);
}];
[operationQueue addOperation:blockOperation1];
[operationQueue addOperation:blockOperation2];
[operationQueue addOperation:blockOperation3];
} 打印结果:
-- ::22.747 TestNSOperation[:] main Thread is 0x7fc279f28130
-- ::31.288 TestNSOperation[:] blockOperation1:current Thread is 0x7fc279e0b8a0
-- ::31.288 TestNSOperation[:] blockOperation3:current Thread is 0x7fc279d661c0
-- ::31.288 TestNSOperation[:] blockOperation2:current Thread is 0x7fc279e064c0
从打印结果可以看出blockOperation1、blockOperation2、blockOperation3运行于不同的线程,是同时运行的,不需要等其他NSOperation,这也表明NSOperationQueue默认是并发执行。如果想要serial执行,则可以设置operationQueue.maxConcurrentOperationCount = 1;
2、不用NSOperationQueue,也可以直接调用NSOperation的start方法,但此时NSOepration运行在当前线程上,测试代码如下:
- (void)testOperationNotQueue
{
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation1:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation2:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation3:current Thread is %p",[NSThread currentThread]);
}];
[blockOperation1 start];
[blockOperation2 start];
[blockOperation3 start];
} //打印结果
-- ::20.497 TestNSOperation[:] main Thread is 0x7fb562427fd0
-- ::20.498 TestNSOperation[:] blockOperation1:current Thread is 0x7fb562427fd0
-- ::20.499 TestNSOperation[:] blockOperation2:current Thread is 0x7fb562427fd0
-- ::20.499 TestNSOperation[:] blockOperation3:current Thread is 0x7fb562427fd0
从打印结果可以看出blockOperation都运行在mainThread上。
3、NSOperation还提供了cancel功能,cancel不是强制把你的代码stop掉,只是改变了NSOperation内部的状态,该功能只能cancel掉Ready、Finish状态的NSOperation,不能cancel掉正在executing的NSOperation,测试代码如下:
- (void)testCancelOperation
{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"start blockOperation1!");
[NSThread sleepForTimeInterval:];
if(blockOperation1.isCancelled)
{
NSLog(@"blockOperation2 cancelled!");
return;
}
NSLog(@"blockOperation1:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation2:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"blockOperation3:current Thread is %p",[NSThread currentThread]);
}];
operationQueue.maxConcurrentOperationCount = ;
[operationQueue addOperation:blockOperation1];
[operationQueue addOperation:blockOperation2];
[operationQueue addOperation:blockOperation3];
[NSThread sleepForTimeInterval:];
NSLog(@"cancel blockOperation1");
[blockOperation1 cancel];
NSLog(@"cancel blockOperation2");
[blockOperation2 cancel];
NSLog(@"cancel blockOperation3");
[blockOperation3 cancel];
}
打印结果:
-- ::26.311 TestNSOperation[:] main Thread is 0x7ff02ae24e70
-- ::26.312 TestNSOperation[:] start blockOperation1!
-- ::28.318 TestNSOperation[:] cancel blockOperation1
-- ::28.318 TestNSOperation[:] cancel blockOperation2
-- ::28.318 TestNSOperation[:] cancel blockOperation3
-- ::36.315 TestNSOperation[:] blockOperation1:current Thread is 0x7ff02af1dec0
从打印结果可以看出不能cancel掉blockOperation1,而blockOperation2和blockOperation3则被成功地取消了。
4、NSOpertion还可以设置依赖,这一功能解决了需要按一定次序执行的situation,不多说直接上代码:
- (void)testOperationWithDependency
{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"start blockOperation1");
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"start blockOperation2");
}];
NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"start blockOperation3");;
}];
[blockOperation1 addDependency:blockOperation2];
[blockOperation2 addDependency:blockOperation3];
[operationQueue addOperation:blockOperation1];
[operationQueue addOperation:blockOperation2];
[operationQueue addOperation:blockOperation3];
}
打印结果:
-- ::06.649 TestNSOperation[:] main Thread is 0x7fdaf9712a00
-- ::09.654 TestNSOperation[:] start blockOperation3
-- ::11.660 TestNSOperation[:] start blockOperation2
-- ::11.660 TestNSOperation[:] start blockOperation1
从打印的结果可以看出只有当依赖的Oepration执行完之后才开始执行自己。
5、当NSOperation添加到NSOperationQueue中,即使进入background(超过10min)NSOperation也会执行,真的不可思议啊,不是app进入到后台后如果不开定位服务、循环播放无声音乐、VOIP就最多运行10min吗?怎么超过10min的NSOperation还能执行啊,麻烦知道的网友告知一下,万分感谢~测试代码如下:
- (void)testBackgroundOperation
{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:*];
NSLog(@"blockOperation1:current Thread is %p",[NSThread currentThread]);
}];
[operationQueue addOperation:blockOperation1];
}
打印结果:
-- ::40.511 TestNSOperation[:] main Thread is 0x7faf41c0da30
-- ::43.095 TestNSOperation[:] applicationDidEnterBackground!
-- ::40.526 TestNSOperation[:] blockOperation1:current Thread is 0x7faf41e02f90
从打印结果可以看出,进入后台11min后,blockOperation1执行了,这是为什么呀!!!!
6、疑问
1、NSOperationQueue具体如何管理NSOperation的,网上也没找到相关文章,希望知道的朋友给个链接;2、测试中发现当NSOperationQueue是局部变量,只要NSOperation添加到NSOperationQueue中,即使程序运行到超出NSOperationQueue的生命周期外(NSOperationQueue变量自动释放了),NSOperation依然可以执行,比如如下代码,operationQueue应该是释放了,但blockOperation1、blockOperation2依然运行,其实这2个疑问都是关于NSOperationQueue如何管理NSOperation的,再次恳求知道的网友给个链接,谢谢哈~
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"main Thread is %p",[NSThread mainThread]);
[self testOperationLeaveLifeCycle];
NSLog(@"leave operationQueue lifecycle");
}
- (void)testOperationLeaveLifeCycle
{
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"blockOperation1:current Thread is %p",[NSThread currentThread]);
}];
NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:];
NSLog(@"blockOperation2:current Thread is %p",[NSThread currentThread]);
}];
[operationQueue addOperation:blockOperation1];
[operationQueue addOperation:blockOperation2];
}
打印结果:
-- ::49.649 TestNSOperation[:] main Thread is 0x7ff7e27241b0
-- ::49.650 TestNSOperation[:] leave operationQueue lifecycle
-- ::59.652 TestNSOperation[:] blockOperation1:current Thread is 0x7ff7e2517d20
-- ::09.653 TestNSOperation[:] blockOperation2:current Thread is 0x7ff7e2608a50
备注:上述所有的测试代码放到github上了,共勉~https://github.com/iOSGeek0829/testNSOperation
iOS自学之NSOperation、NSOperationQueue、Background的更多相关文章
- IOS多线程(NSOperation,NSOperationQueue)
含义:NSOperation,NSOperationQueue是什么. The NSOperation class is an abstract class you use to encapsulat ...
- iOS开发之NSOperation & NSOperationQueue
1.简介 (1) NSOperationQueue(操作队列)是由GCD提供的队列模型的Cocoa抽象,是一套Objective-C的API,为了使并发(多线程)编程变得更加简单,但效率比GCD略低. ...
- iOS中的多线程NSThread/GCD/NSOperation & NSOperationQueue
iOS多线程有四套多线程方案: Pthreads NSThread GCD NSOperation & NSOperationQueue 接下来我来一个一个介绍他们 Pthreads 在类Un ...
- iOS 多线程之 NSOperation 的基本使用
1.NSOperation,NSOperationQueue 简介 NSOperation,NSOperationQueue是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.NSO ...
- iOS开发-多线程NSOperation和NSOperationQueue
上一篇文章稍微提及了一下NSThread的使用,NSThread能直观地控制线程对象,不过需要自己管理线程的生命周期,线程同步,用起来比较繁琐,而且比较容易出错.不过Apple给出了自己的解决方案NS ...
- IOS NSOperation&NSOperationQueue
NSOperation与NSOperationQueue的基本理论如下: 1.NSOperationQueue代表一个FIFO的队列,它负责管理系统提交的多个NSOperation,NSOp ...
- iOS 并发:NSOperation 与调度队列入门(1)
一直以来,并发都被视为 iOS 开发中的「洪水猛兽」.许多开发者都将其视为危险地带,唯恐避之而不及.更有谣传认为,多线程代码应该尽力避免.笔者同意,如果你对并发的了解不够深入,就容易造成危险.但是,危 ...
- iOS之多线程NSOperation
目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...
- iOS多线程编程--NSOperation(转)
这篇文章写得非常不错,基础用法都涉及到了,我把文章提到的例子都写到了demo里面, 原文地址: iOS多线程--彻底学会多线程之『NSOperation』 demo下载:https://github. ...
随机推荐
- Block的引用循环问题 (ARC & non-ARC)
2010年WWDC发布iOS4时Apple对Objective-C进行了一次重要的升级:支持Block.说到底这东西就是闭包,其他高级语音例如Java和C++已有支持,第一次使用Block感觉满简单好 ...
- 剑指OFFER之第一个只出现一次的字符(九度OJ1283)
题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...
- Jsp的三、七、九
1.jsp的三个编译指令 <%page %> <%taglib %> <%include %> 2.jsp的七个动作指令 forward param include ...
- 使用openssl库实现des,3des加密
原文地址: 使用openssl库实现des,3des加密 主要是调整了一下格式,以及一些变量的类型,以解决在VC2008下无法编译通过的问题. #include <stdio.h> #in ...
- BZOJ [ZJOI2008]泡泡堂BNB 贪心
[ZJOI2008]泡泡堂BNB Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/proble ...
- 块设备驱动之NAND FLASH驱动程序
转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 watermark/2/text/aHR0cDov ...
- spring mvc+ajax分页
分页大致思路:页面每次把当前页传到后台并获得从后台传过来的json数据,解析后布局到这个页面上. 1.服务端代码: @Controller public class MemcachedContrlle ...
- Nginx动静分离经典
Nginx:安装nginx之前需要安装pcre包和zlib以支持重写,正则以及网页压缩等等]把所需的包下载到/usr/src下[根据自己的习惯,路径可以改变]1.首先安装pcre: cd /usr/s ...
- [置顶] 【玩转cocos2d-x之七】场景类CCScene和布景类CCLayer
原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/12708811 场景类CCScene和布景类CCLayer都是作为一个容器来使 ...
- SharePoint 2013+ Sqlserver 2014 Kerberos 配置传奇, 最终的解决方案 验证。
SharePoint 2013+ Sqlserver 2014 Kerberos 配置传奇. 1,安装数据库,我就不多说安装,客户一定要注意. 我将参照以下实施例和账户. 2,建立DNS,假设没有DN ...