Objective-C 异步任务

Objective-C 异步任务

Objective-C提供了多种不同的异步处理方式,这里主要看3种比较常用的方式:NSThread、Grand Central Dispatch与NSOperationQueue。


一、NSThread

NSThread是OC提供的线程类,基于此,我们可以很方便地开辟线程。在OS X V10.5之前,该类只提供了一种开启新线程的方法(如:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. [NSThread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil]  
), 该方法调用后线程会马上执行;在OS X V10.5之后(包括V10.5),我们可以用NSThread创建一个线程(),然后通过调用start方法开始执行线程(如:
[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. NSThread *thread=[[[NSThread alloc] initWithTarget:self selector:@selector(task) object:nil] autorelease];  
  2. [thread start];  
)。


另外 ,内存管理对于线程来说非常重要。需要将task方法的代码放到autoreleasepool中。在非GC项目中,OC可以凭借autoreleasepool使用内存资源,然后在需要的时候回收资源。每个线程都需要有autoreleasepool,否则应用中会出现内存泄露


二、主线程与后台线程通信

NSObject类提供了performSelectorOnMainThread:withObject:waitUntilDone:方法用执行主线程中方法。我们可以通过这个方法从后台线程通知主线程做一些界面处理。这里说明一下,该方法最后一个参数是一个BOOL值。如果是YES,则表示当前线程会阻塞,直到指定的任务在主线程中执行完;如果是NO,则不阻塞当前线程。


三、线程同步

我们可以使用NSLock锁定线程,然后在任务执行完后再解锁。如:

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. -(void)task  
  2. {  
  3.     [threadLock lock];  
  4.     @autoreleasepool {  
  5.          
  6.        ... ...  
  7.     }  
  8.     [threadLock unlock];  
  9. }  

除了NSLock,我们还可以使用@synchronized关键字。@synchronized与NSLock解决的都是同样的线程问题,但实现方式不同,@synchronized可以处理异常。此外,@synchronized方式要比NSLock具备更好的性能


四、GCD

GCD技术在OSX 10.6与IOS 4中被引入,其针对多核应用进行了优化,在拥有多个处理器的计算机上应用的性能会极大提升。GCD的出现减轻了再多核上编程的负担,也减少了不少线程管理的麻烦。GCD是一个系统级别的技术,因此我们可以在任意级别的代码中使用它。GCD决定需要多少线程并安排它们的运行进度。因为它是运行在系统级别上得,所以可以平衡应用程序所有内容的加载。


1、添加任务的方式

有两种方式可以向队列中添加任务。

同步:队列会一直等待前面的任务结束。

异步:添加后,不必等待任务结束,函数会立即返回。推荐优先使用这种方式,因为它不会阻塞其他任务的执行。


2、调度队列

GCD使用调度队列(dispatch queue),它与线程很相似但使用起来更简单。只需要将任务添加到队列中,系统就会执行它。一共有以下3种类型的队列。


连续队列:每个连续队列都会根据指派的顺序执行任务。我们可以按自己的想法创建多个连续队列,它们会并行操作任务。有时候有一串任务需要按照一定的顺序执行,这时便可以使用连续队列,任务执行的顺序为先入先出(FIFO)。

(1)异步添加任务

[objc]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. dispatch_queue_t serial_queue= dispatch_queue_create("com.jerry.SerialQueue"NULL);  
  2.     dispatch_async(serial_queue, ^{  
  3.         for(int i=0;i<100;i++){  
  4.             NSLog(@"task::111-------%i",i);  
  5.         }  
  6.       
  7.     });  
  8.       
  9.     NSLog(@"dispatched task 111");  
  10.       
  11.     dispatch_async(serial_queue, ^{  
  12.         for(int i=0;i<100;i++){  
  13.             NSLog(@"task::222-------%i",i);  
  14.         }  
  15.           
  16.     });  
  17.       
  18.     NSLog(@"dispatched task 222");  
  19.       
  20.     dispatch_async(serial_queue, ^{  
  21.         for(int i=0;i<100;i++){  
  22.             NSLog(@"task::333-------%i",i);  
  23.         }  
  24.           
  25.     });  
  26.       
  27.     NSLog(@"dispatched task 333");  

下面是执行结果(由于输出内容太长,这里只截取部分):

      

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值