iphone中的多线程

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

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

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

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



编写最简单的示例

先写个最简单的示例。


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

头文件:
  1. @interface MyTask : NSOperation { 
  2.     int operationId; 
  3. }

  4. @property int operationId;

  5. @end
复制代码
这里的operationId属性不是必须的,是我想在后面标识区分多个Task的标识位。

m文件:
  1. @implementation MyTask

  2. @synthesize operationId;

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

  8. @end
复制代码
这里模拟了一个耗时10秒钟的操作。

下面需要把Task加入到队列中:
  1. - (void)viewDidLoad { 
  2.     [super viewDidLoad]; 
  3.     queue=[[NSOperationQueue alloc] init]; 
  4.     
  5.     int index=1; 
  6.     MyTask *task=[[[MyTask alloc] init] autorelease]; 
  7.     task.operationId=index++; 
  8.          
  9.     [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)增加多个操作,比如这样:
  1. - (void)viewDidLoad { 
  2.     [super viewDidLoad]; 
  3.     queue=[[NSOperationQueue alloc] init]; 
  4.     
  5.     int index=1; 
  6.     MyTask *task=[[[MyTask alloc] init] autorelease]; 
  7.     task.operationId=index++;     
  8.     [queue addOperation:task]; 
  9.     
  10.     task=[[[MyTask alloc] init] autorelease]; 
  11.     task.operationId=index++;

  12.     [queue addOperation:task]; 
  13. }
复制代码
那么打印出的内容是不定的,有可能是这样:

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.




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

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



处理操作之间的依赖关系

如果操作直接有依赖关系,比如第二个操作必须等第一个操作结束后再执行,需要这样写:
  1. queue=[[NSOperationQueue alloc] init];

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

  5. [queue addOperation:task];

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

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

  12. [queue addOperation:task];
复制代码
这样,即使是多线程情况下,可以看到操作是严格按照先后次序执行的。



控制线程池中的线程数

可以通过类似下面的代码:
  1. [queue setMaxConcurrentOperationCount:2];
复制代码




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



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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值