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. ...
随机推荐
- iOS开发—字典转模型,KVC设计模式
iOS开发UI基础—字典转模型 开发中,通常使用第三方框架可以很快的实现通过字典转模型,通过plist创建模型,将字典的键值对转成模型属性,将模型转成字典,通过模型数组来创建一个字典数组,通过字典数组 ...
- stm32 堆和栈(stm32 Heap & Stack)【worldsing笔记】
关于堆和栈已经是程序员的一个月经话题,大部分有是基于os层来聊的. 那么,在赤裸裸的单片机下的堆和栈是什么样的分布呢?以下是网摘: 刚接手STM32时,你只编写一个 int main() ...
- 【PAT Advanced Level】1004. Counting Leaves (30)
利用广度优先搜索,找出每层的叶子节点的个数. #include <iostream> #include <vector> #include <queue> #inc ...
- React-native 中的触摸响应功能
我们在做APP的时候,与桌面应用系统不同的是触摸响应. web页面对触摸响应的支持和原生的APP有着很大的差异. 基本用法 componentWillMount: function() { this. ...
- ASP.Net Core-TagHelpers
当我们新建了一个.Net Core类型的Project时,我们会看到页面上有类似于这样的代码: 当我们运行项目,查看源代码会发现,浏览器中的就是Html代: 那么,为什么我们在页面写的代码会转化为ht ...
- Css基础-介绍及语法
css 文件后缀.css 基础语法: selector { property:value } 例如: h1 {color:red;font-size:14px;} color:字体颜色 font-s ...
- Dev XtraTreeList 学习
本文转载:http://www.cnblogs.com/VincentLuo/archive/2012/01/06/2313983.html 一.设置载请保留地址http://www.cnblogs. ...
- Codeforces Round #200 (Div. 1)D. Water Tree dfs序
D. Water Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/343/problem/ ...
- 基于华为Java编程规范的Eclipse checkStyle.xml
发现项目组成员代码规范存在较大的问题,于是就在华为编程规范的基础上制定了这份checkStyle.xml文档,至于Eclipse怎么安装checkStyle插件以及该插件怎么使用请自行Google之. ...
- [AngularJS] Accessible Button Events
Often buttons need to be handled by JavaScript, and if done improperly it can lead to accessibility ...