`
lizaochengwen
  • 浏览: 647980 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用NSOperationQueue简化多线程开发(转)

阅读更多
多线程开发是一件需要特别精心的事情,即使是对有多年开发经验的工程师来说。

为了能让初级开发工程师也能使用多线程,同时还要简化复杂性。各种编程工具提供了各自的办法。对于iOS来说,建议在尽可能的情况下避免直接操作线程,使用比如NSOperationQueue这样的机制。

可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。

你可以设置线程池中只有一个线程,这样,各个操作就可以认为是近似的顺序执行了。为什么说是近似呢,后面会做解释。



编写最简单的示例

先写个最简单的示例。


编写一个NSOperation的子类,只需实现main方法。这里非常类似Java的Thread,你可以继承它,并覆盖run方法,在该方法里面写入需要执行的代码。这里的main方法和run方法作用是相似的。

头文件:

@interface MyTask : NSOperation { 
    int operationId; 
}

@property int operationId;

@end

这里的operationId属性不是必须的,是我想在后面标识区分多个Task的标识位。

m文件:

@implementation MyTask

@synthesize operationId;

- (void)main{ 
    NSLog(@"task %i run … ",operationId); 
    [NSThread sleepForTimeInterval:10]; 
    NSLog(@"task %i is finished. ",operationId); 
}

@end

这里模拟了一个耗时10秒钟的操作。

下面需要把Task加入到队列中:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    queue=[[NSOperationQueue alloc] init]; 
    
    int index=1; 
    MyTask *task=[[[MyTask alloc] init] autorelease]; 
    task.operationId=index++; 
         
    [queue addOperation:task];

我直接找了个Controller的方法写上了。运行结果是,界面出现了,而task还未执行完,说明是多线程的。10秒钟后,日志打印完毕,类似这样:



2011-07-18 15:59:14.622 MultiThreadTest[24271:6103] task 1 run …
2011-07-18 15:59:24.623 MultiThreadTest[24271:6103] task 1 is finished.


可以向操作队列(NSOperationQueue)增加多个操作,比如这样:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    queue=[[NSOperationQueue alloc] init]; 
    
    int index=1; 
    MyTask *task=[[[MyTask alloc] init] autorelease]; 
    task.operationId=index++;     
    [queue addOperation:task]; 
    
    task=[[[MyTask alloc] init] autorelease]; 
    task.operationId=index++;

    [queue addOperation:task]; 
}

那么打印出的内容是不定的,有可能是这样:



2011-07-18 15:49:48.087 MultiThreadTest[24139:6203] task 1 run …
2011-07-18 15:49:48.087 MultiThreadTest[24139:1903] task 2 run …
2011-07-18 15:49:58.122 MultiThreadTest[24139:6203] task 1 is finished.
2011-07-18 15:49:58.122 MultiThreadTest[24139:1903] task 2 is finished.


甚至有可能是这样:



2011-07-18 15:52:24.686 MultiThreadTest[24168:1b03] task 2 run …
2011-07-18 15:52:24.685 MultiThreadTest[24168:6003] task 1 run …
2011-07-18 15:52:34.708 MultiThreadTest[24168:1b03] task 2 is finished.
2011-07-18 15:52:34.708 MultiThreadTest[24168:6003] task 1 is finished.




因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。

那么,如果需要严格意义的顺序执行,怎么办呢?



处理操作之间的依赖关系

如果操作直接有依赖关系,比如第二个操作必须等第一个操作结束后再执行,需要这样写:

queue=[[NSOperationQueue alloc] init];

int index=1; 
MyTask *task=[[[MyTask alloc] init] autorelease]; 
task.operationId=index++;

[queue addOperation:task];

task=[[[MyTask alloc] init] autorelease]; 
task.operationId=index++;

if ([[queue operations] count]>0) { 
    MyTask *theBeforeTask=[[queue operations] lastObject]; 
    [task addDependency:theBeforeTask]; 
}

[queue addOperation:task];

这样,即使是多线程情况下,可以看到操作是严格按照先后次序执行的。



控制线程池中的线程数

可以通过类似下面的代码:

[queue setMaxConcurrentOperationCount:2];

来设置线程池中的线程数,也就是并发操作数。默认情况下是-1,也就是没有限制,同时运行队列中的全部操作。

转自:http://www.codeios.com/thread-1688-1-1.html

分享到:
评论

相关推荐

    ios多线程开发的常用四种方式和基本使用

    ios多线程开发的常用四种方式和基本使用,pthread、NSThread、NSOperation\NSOperationQueue、GCD

    多线程GCD,NSThread,NSOperationQueue,详细解释Demo

    该demo详细解释了gcd NSThread NSOperationQueue的用法.详细解释了子线程中如何刷新UI

    iOS多线程与网络开发之NSOperation示例代码

    配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加到NSOperationQueue中 ...

    iOS多线程应用开发中使用NSOperation类的基本方法

    NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation...

    NSOperation_NSOperationQueue_Demo

    NSOperation NSOperationQueue demo 项目讲述了 NSOperation 和 NSOperationQueue 怎么使用。适合学习

    IOS编程中使用多线程

    在app store中的很多应用程序非常...然而,幸运的是apple从os x10.5在这方面做了很多的改进,NSThread的引入,使得开发多线程应用程序容易多了。除此之外,它们还引入了两个全新的类,NSOperation和NSOperationQueue。

    ios的三种多线程技术

    #iOS的三种多线程技术 和特性 1.NSThread 2.NSOperation/NSOperationQueue 3.GCD (大中心调度)

    OptimizedNetworking:iOS 项目展示如何使用 NSOperationQueue 优化网络

    该项目旨在提供一种优化网络的简单方法,重点是使用 NSOperationQueue,而不是简单地使用 NSURLConnection 的异步 API 或使用 GCD 将工作卸载到辅助队列,后者对并发连接的数量和能力的控制较少取消。 批量下载多个...

    iOS 多线程总结

    对iOS的多线程方式做的总结;Pthreads,NSThread,GCD,NSOperation/NSOperationQueue

    ios-多线程实现(摇奖机).zip

    利用 NSOperationQueue 实现摇奖机功能。 掌握 NSOperationQueue 的暂停功能结合业务实现效果

    NSOperationQueue-CompletionBlock:NSOperationQueue的完成块

    NSOperationQueue + CompletionBlock NSOperationQueue的完成块。 乍看上去 Swift import NSOperationQueue_CompletionBlock let queue = NSOperationQueue () queue. completionBlock = { NSLog ( " I'm done! ...

    在IOS中为什么使用多线程及多线程实现的三种方法

    给大家介绍在IOS中为什么使用多线程及多线程实现的三种方法,基本上使用这三种方法实现多线程(NSThread Grand Centeral Dispatch(GCD) NSOperation和NSOperationQueue),感兴趣的朋友可以参考下本

    IOS多线程编程的3种实现方法

    这是最轻量级的多线程的方法,使用起来最直观的多线程编程方法。但是因为需要自己管理线程的生命周期,线程同步。经常使用NSThread进行调试,在实际项目中不推荐使用。 //获取当前线程 NSThread *current = ...

    iOS多线程编程之NSThread的使用案例

    2、Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue的使用)3、GCD 全称:Grand Central Dispatch( iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用) 这三种编程方式从上到下,抽象度...

    IOS多线程编程系类

    1.、NSThread2、CocoaNSOperation(IOS多线程编程之NSOperation和NSOperationQueue的使用)3、GCD全称:GrandCentralDispatch(IOS多线程编程之Grand CentralDispatch(GCD)介绍和使用)这三种编程方式从上到下,抽象...

    藏经阁-深入剖析iOS性能优化.pdf

    我们可以使用 NSOperationQueue 来执行多个任务,并使用 maxConcurrentOperationCount 属性来控制并发任务的数量。 I/O 优化 I/O 优化是移动应用开发中非常重要的一个方面。我们可以使用 NSCache 来缓存频繁访问的...

    TRVSURLSessionOperation:NSURLSession和NSOperationQueue一起工作

    TRVSURLSessionOperation是一个NSOperation子类,该子类包装了NSURLSessionTask因此您可以在NSOperationQueue使用它们。 有了这个,您可以: 计划网络请求(即运行请求A然后请求B,并赋予请求优先级) 限制并发...

    iOS开发实习面试题目

    你⽤用哪些办法实现过多线程? GCD和NSOperationQueue的⽐比较,各⾃自优缺点是什么,平时你是怎么使⽤用的? weak,assign,strong的意义和区别? atomic,nonatomic的意义和区别? OC中有没有多继承?OC中怎么实现多...

Global site tag (gtag.js) - Google Analytics