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. ...
随机推荐
- IE6完美解决fixed方法
ie6对position:fixed不支持,网上有很多解决方法,有的在ie6,ie7上调试成功后,在ie8上又不好使,div层还是跟随滚动条浮 动:以下总结方法,在ie6,ie7,ie8上都调试成功, ...
- unable to load default svn client myeclipse SVN安装,wen7 64位安装SVN
在安装完后连接svn时出现unable to load default svn client的错误提示,百度知道是版本不对,我安装的是1.8的版本,插件按成1.6的了,只需下载1.8插件安装就行了 安 ...
- SD卡fat文件系统移植
经过充分的研究,发现fatfs文件系统移植的比较简单!因为代码都已经被别人做好了!我们只需把io层稍稍做个处理就ok了: 至于sd卡的驱动请看我这篇博客:http://blog.csdn.net/ie ...
- CentOS6.5安装nginx及负载均衡配置
所有的安装包可以去以下地址下载,或者自行去官网下载,下面都有介绍. 所有安装包地址:http://download.csdn.net/detail/carboncomputer/9238037 原文地 ...
- ECSHOP在线手册之布局参考图-首页 index.dwt
A.logo替换 1,设置方法 后台商店设置里,上传logo就行,注意logo的名称必须是logo.gif 2,代码相关 page_header.lbi 中 <a href=" ...
- Mac下移动硬盘不能粘贴
不想格式化,安装 Paragon NTFS 10.0.2 from:http://www.nowmac.com/support/mac/664.html 就可以解决
- javasctipt显示几分钟前、几天前等
jsp页面: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ...
- struts2标签具体解释
要在jsp中使用Struts2的标志,先要指明标志的引入.通过jsp的代码的顶部增加下面的代码: <%@taglib prefix="s" uri="/struts ...
- liveness 生存性/活性
翻译了两篇,这篇就不翻译了,自己写吧. 对于线程来说除了安全性,我们还应该重视它的生存性(我认为翻译成三个字说着比較顺). 为了保证线程安全,我们往往须要用到同步,可是同步限制了线程的运行,线程必须为 ...
- 区域医疗移动医疗影像解决方案2--基于FLEX的PACS
基于Flex的PACS和基于HTML5的PACS,都不是基于DICOM的WADO的方式,即所有的图像操作,移动.缩放.旋转.测量.伪彩.窗宽窗位调整等都是在本地浏览器能够完成,不用和服务器进行频繁的交 ...