您的位置:首页 > 移动开发 > IOS开发

iOS多线程开发(五)---GCD(Grand Central Dispatch)

2014-01-12 12:22 357 查看
GCD 原理
-将一段(Block)代码作为特定任务,放到指定的队列(queue:Serial(串行,同时只能执行一个任务)/globel(并行,同时可执行多个任务,但执行顺序是随机的)/main(全局的Serial,在主线程里面执行任务)
dispatch queue)里,进行同步/异步(dispatch_sync/dispatch_async)处理。根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。dispatch_sync/dispatch_async的意思就是将任务进行同步/异步并行处理,不一定需要一个任务处理完后才能处理下一个

-一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
GCD 概述
1. GCD 包含于 libSystem.dylib
2. 可供所有程序使用.
- #include <dispatch/dispatch.h>
3. GCD API 提供 block-based and function-based variants
- 目前仅提供 block-based API
GCD总结
1. Blocks
- dispatch_async()
2. Queues
- Lightweight list of blocks
- Enqueue/dequeue is FIFO
-dispatch queue分为下面三种:
   -Serial 又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
   -Concurrent 又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。
   -Main dispatch queue 它是全局可用的serial queue,它是在应用程序主线程上执行任务的。
3. dispatch_get_main_queue()
- Main thread/main runloop(获取主线程的队列)
4. dispatch_queue_create()
- Automatic helper thread, private dispatch queues
GCD的好处
1. 高效 - More CPU cycles available for your code
2. 使用方便
- Blocks are easy to use
- Queues are inherently producer/consumer
3. Systemwide perspective
- Only the OS can balance unrelated subsystems
兼容性
1. Existing threading and synchronization primitives are 100% compatible
2. GCD threads are wrapped POSIX threads
- Do not cancel, exit, kill, join, or detach GCD threads
3. GCD reuses threads
- Restore any per-thread state changed within a block
多线程
Session 206已提到此内容。
锁定资源
1. 对关键资源进行互斥访问。
2. 在线程中按序访问共享资源。
3. Ensure data integrity
没有GCD的代码
- (void)updateImageCacheWithImg:(UIImage*)img

{

  NSLock *nLock = self.imageCacheLock;

  [nLock lock];

  // Critical section

  if ([self.imageCache containsObj:img])

  {

    [nLock unlock]; // Don't forget to unlock

    return;

  }

  [self.imageCache addObj:img];

  [nLock unlock];

}

GCD代码
- (void)updateImageCacheWithImg:(NSImage*)img
{
     dispatch_queue_t queue = self.imageCacheQueue;
     dispatch_sync(queue, ^{ //You can change dispatch_sync to dispatch_async to defer critical section
         // Critical section
         UIImage *cellImage = [self loadMyImageFromNetwork:image_url];
         // 将图片cache到本地
         [self cacheImage:cellImage];
         if ([self.imageCache containsObj:cellImage]) {
             return;
          }
          [self.imageCache addObj:cellImage];
          });
}
dispatch_sync/dispatch_async的意思就是将任务进行同步/异步并行处理,不一定需要一个任务处理完后才能处理下一个。以上代码loadMyImageFromNetwork的意思就是从网络中读取图片,这个任务交给network_queue来处理。这样读取图片的时间过长也不会阻塞主线程界面的处理。
dispatch_async(network_queue, ^{    
    UIImage *cellImage = [self loadMyImageFromNetwork:image_url];    
    // 将图片cache到本地    
    [self cacheImage:cellImage];    
    
   // 回到主线程    
   dispatch_async(dispatch_get_main_queue(), ^{    
      // 显示图片到界面    
      [self displayImageToTableView:cellImage];    
   }];    
        
} );  
线程间通信
通过以下方法 (Without GCD)
– performSelectorOnMainThread:withObject:waitUntilDone:
– performSelector:onThread:withObject:waitUntilDone:
– performSelector:withObject:afterDelay:
– performSelectorInBackground:withObject:
GCD 代码,等同于 performSelector:onThread:withObject:waitUntilDone:
// waitUntilDone: NO
dispatch_async(queue, ^{
[myObject doSomething:foo withData:bar];
});
// waitUntilDone: YES
dispatch_sync(queue, ^{
[myObject doSomething:foo withData:bar];
});
GCD代码, 等同于 performSelector:withObject:afterDelay:
dispatch_time_t delay;
delay = dispatch_time(DISPATCH_TIME_NOW, 50000 /* 50μs */);
dispatch_after(delay, queue, ^{ [myObject doSomething:foo withData:bar];});
GCD代码,等同于 performSelectorInBackground:withObject:
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{ [myObject doSomething:foo withData:bar];});

Global Queues

1. Enqueue/dequeue is FIFO

2. Concurrent execution- Non-FIFO completion order

3. dispatch_get_global_queue(priority, 0)

4. Global queues map GCD activity to real threads

5. Priority bands- DISPATCH_QUEUE_PRIORITY_HIGH - DISPATCH_QUEUE_PRIORITY_DEFAULT - DISPATCH_QUEUE_PRIORITY_LOW

下面三节讲述了很多内容,但我还没有理解。如有兴趣,请看原始视频。- Dispatch Sources

- Source Cancellation- Target Queues

GCD对象
GCD方法大全

管理对象的生命周期
1. Ensure objects captured by blocks are valid when blocks are executed
- Objects must be retained and released around asynchronous operations
2. Objective-C objects captured by blocks are auto-retained and auto-released
3. Other objects captured by blocks must be retained by your code
- CFRetain()/CFRelease()
- dispatch_retain()/dispatch_release()
挂起和恢复
1. Suspend and resume only affects queues and sources you create
- Sources are created suspended
2. Suspension is asynchronous
- Takes effect between blocks
3. Your queues can predictably suspend objects that target them
程序上下文
1. Applications can attach custom data to GCD objects
- dispatch_set_context()/dispatch_get_context()
2. Optional finalizer callback
- dispatch_set_finalizer_f()
- Allows attached context to be freed with object
- Called on the target queue of the object
WWDC2010 Session211 Simplifying iPhone App Development with Grand Central Dispatch
Daniel Steffen - Core OS
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: