NSInvocationOperation:用在任务代码以函数的方式进行封装的情形,通过@selector的方式调用。
NSBlockOperation:用在任务代码以代码块对象的方式进行封装的情形。
使用代码块时的注意事项:
- 代码块中引用指针对象和大的数据结构时,应注意在代码块被分配到线程执行时,指针指向的数据仍然是有效的。
Serial:(又称为private dispatch queues)
同一个分发队列中的任务是串行执行的,该队列确保其中的任务是按顺序一个一个执行的。这个队列对象是基于引用计数的,操作它时需注意分配和释放引用记数。
创建该队列代码:
dispatch_queue_t queue; |
queue = dispatch_queue_create("com.example.MyQueue", NULL); |
Concurrent:(又称为global dispatch queue)
分发队列中的任务是并行执行的。
获取该队列代码:
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
Main dispatch queue:
应用程序的主线程,实际上它也是Serail线程,但是它是全局的。
3. Execute Queues
队列加载任务:
有两种方式,同步加入、异步加入。同步的方式将阻塞当前线程,直到任务线程执行完毕才继续执行。
同步方式:dispatch_sync
异步方式:dispatch_async
// Create the semaphore, specifying the initial pool size |
dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2); |
|
// Wait for a free file descriptor |
dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER); |
fd = open("/etc/services", O_RDONLY); |
|
// Release the file descriptor when done |
close(fd); |
dispatch_semaphore_signal(fd_sema); |
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); |
dispatch_group_t group = dispatch_group_create(); |
// Add a task to the group |
dispatch_group_async(group, queue, ^{ |
// Some asynchronous work |
}); |
// Do some other work while the tasks execute. |
// When you cannot make any more forward progress, |
// wait on the group to block the current thread. |
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); |
|
// Release the group when it is no longer needed. |
dispatch_release(group); |
- Timer dispatch sources
产生周期性的时间通知. - Signal dispatch sources
传统的linux/unix系统信号通知. - Descriptor sources
基于文件、socket套接字的描述符通知: -
- 当有数据可以读时
- 当数据可以写时
- 当文件系统中的文件被删除、移动、重命名时
- 当文件元信息被修改时
- Process dispatch sources
当进程发生变化时通知: -
- 进程退出
- 当进程执行类fork/exec系统调用
- 当一个信号被发送到进程时
- Mach port dispatch sources
Mach-related相关事件通知. - Custom dispatch sources
用户自定义事件.