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的更多相关文章

  1. IOS多线程(NSOperation,NSOperationQueue)

    含义:NSOperation,NSOperationQueue是什么. The NSOperation class is an abstract class you use to encapsulat ...

  2. iOS开发之NSOperation & NSOperationQueue

    1.简介 (1) NSOperationQueue(操作队列)是由GCD提供的队列模型的Cocoa抽象,是一套Objective-C的API,为了使并发(多线程)编程变得更加简单,但效率比GCD略低. ...

  3. iOS中的多线程NSThread/GCD/NSOperation & NSOperationQueue

    iOS多线程有四套多线程方案: Pthreads NSThread GCD NSOperation & NSOperationQueue 接下来我来一个一个介绍他们 Pthreads 在类Un ...

  4. iOS 多线程之 NSOperation 的基本使用

    1.NSOperation,NSOperationQueue 简介 NSOperation,NSOperationQueue是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.NSO ...

  5. iOS开发-多线程NSOperation和NSOperationQueue

    上一篇文章稍微提及了一下NSThread的使用,NSThread能直观地控制线程对象,不过需要自己管理线程的生命周期,线程同步,用起来比较繁琐,而且比较容易出错.不过Apple给出了自己的解决方案NS ...

  6. IOS NSOperation&NSOperationQueue

    NSOperation与NSOperationQueue的基本理论如下:      1.NSOperationQueue代表一个FIFO的队列,它负责管理系统提交的多个NSOperation,NSOp ...

  7. iOS 并发:NSOperation 与调度队列入门(1)

    一直以来,并发都被视为 iOS 开发中的「洪水猛兽」.许多开发者都将其视为危险地带,唯恐避之而不及.更有谣传认为,多线程代码应该尽力避免.笔者同意,如果你对并发的了解不够深入,就容易造成危险.但是,危 ...

  8. iOS之多线程NSOperation

    目前在 iOS 和 OS X 中有两套先进的同步 API 可供我们使用:NSOperation 和 GCD .其中 GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实 ...

  9. iOS多线程编程--NSOperation(转)

    这篇文章写得非常不错,基础用法都涉及到了,我把文章提到的例子都写到了demo里面, 原文地址: iOS多线程--彻底学会多线程之『NSOperation』 demo下载:https://github. ...

随机推荐

  1. ECSHOP在线手册之模板结构说明 (适用版本v2.7.3)

    名称 类型 备注(作用或意义) 文件(目录)名可否更改 images 目录 存放模板图片目录 不可更改 library 目录 存放模板库文件目录 不可更改 screenshot.png 图片 用于“后 ...

  2. utf8乱码解决方案[适合tomcat部署的jsp应用]

    转:http://blog.csdn.net/cn_gaowei/article/details/6673539 1.       java类: CharacterEncodingFilter  im ...

  3. 使用ttXactAdmin、ttSQLCmdCacheInfo、ttSQLCmdQueryPlan获取SQL相关具体信息[TimesTen运维]

    使用ttXactAdmin.ttSQLCmdCacheInfo.ttSQLCmdQueryPlan获取SQL相关具体信息,适合于tt11以上版本号. $ ttversion TimesTen Rele ...

  4. linux修改文件权限和用户组管理小结

    如何在linux下修改组权限 chmod g+r path/file 加读权限 当前目录 chmod -R g+r path/file 加读权限 当前目录以及子目录 g-r 减读权限g+w 加写权限g ...

  5. HDU 5477 A Sweet Journey 水题

    A Sweet Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  6. 【项目经验】如何用TexturePacker & Physicseditor开发游戏

    首先感谢Andreas的license.先广告一下Andreas. ------------------------------------------------------------------ ...

  7. [Node.js] Using npm link to use node modules that are "in progress"

    It is some times convenient, even necessary, to make use of a module that you are working on before ...

  8. python抓取伯乐在线的全部文章,对标题分词后存入mongodb中

    依赖包: 1.pymongo 2.jieba # -*- coding: utf-8 -*- """ @author: jiangfuqiang "" ...

  9. ulimit 命令详解

      Linux对于每个用户,系统限制其最大进程数.为提高性能,可以根据设备资源情况,设置各linux 用户的最大进程数 可以用ulimit -a 来显示当前的各种用户进程限制. 下面我把某linux用 ...

  10. [Effective C++ --014]在资源管理类中小心copying行为

    第一节 <背景> 条款13中讲到“资源取得的时机便是初始化时机”并由此引出“以对象管理资源”的概念.通常情况下使用std中的auto_ptr(智能指针)和tr1::shared_ptr(引 ...