Dispatch Queue
2018-12-23 本文已影响0人
yxibng
queue types
- Serial
- Concurrent
- Main dispatch queue
Queue-Related Technologies
- Dispatch groups
- Dispatch semaphores
- Dispatch sources
- 全局队列(Concurrent)
可选的优先级:
- DISPATCH_QUEUE_PRIORITY_HIGH
- DISPATCH_QUEUE_PRIORITY_DEFAULT
- DISPATCH_QUEUE_PRIORITY_LOW
- DISPATCH_QUEUE_PRIORITY_BACKGROUND
//参数1:队列优先级
//参数2:保留字段,传 0
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- 创建队列
//参数1:队列的名字 com.example.queue
//队列属性:DISPATCH_QUEUE_SERIAL(orNULL)或者 DISPATCH_QUEUE_CONCURRENT
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
- 运行时获取队列
dispatch_get_current_queue - 内存管理
Dispatch queues and other dispatch objects are reference-counted data types.
也是一种引用技术的类型
MRC下管理内存使用:
- 设置和获取队列上下文数据
- dispatch_set_context
- dispatch_get_context
- dispatch_set_finalizer_f 提供队列销毁时的处理
创建队列上下文,并提供清理函数,example:
typedef struct {
char *name;
int age;
char *sex;
} MyDataContext;
- (void)testCreateQueueWithContext {
dispatch_queue_t queue = [self createQueueWithContext];
//add tasks
dispatch_async(queue, ^{
printf("task1\n");
MyDataContext *context = dispatch_get_context(queue);
printf("name = %s, age = %d, sex = %s\n",context->name, context->age, context->sex);
//modify the context
context->age = 11;
});
dispatch_async(queue, ^{
printf("task2\n");
MyDataContext *context = dispatch_get_context(queue);
printf("name = %s, age = %d, sex = %s\n",context->name, context->age, context->sex);
});
}
- (dispatch_queue_t)createQueueWithContext {
MyDataContext *data = (MyDataContext *)malloc(sizeof(MyDataContext));
data->name = "context";
data->age = 10;
data->sex = "male";
dispatch_queue_t queue = dispatch_queue_create("com.example.queue.withcontext", DISPATCH_QUEUE_SERIAL);
dispatch_set_context(queue, data);
dispatch_set_finalizer_f(queue, &myFinalizerFunction);
return queue;
}
void myFinalizerFunction(void *context)
{
MyDataContext* theData = (MyDataContext*)context;
// Clean up the contents of the structure
myCleanUpDataContextFunction(theData);
// Now release the structure itself.
free(theData);
}
void myCleanUpDataContextFunction(void *context)
{
MyDataContext* theData = (MyDataContext*)context;
printf("%s",__FUNCTION__);
printf("name = %s, age = %d, sex = %s",theData->name, theData->age, theData->sex);
}
- 任务完成时,执行一个block
- (void)testPerformingCompletionBlockWhenTaskIsDone {
dispatch_queue_t queue = dispatch_queue_create("com.example.queue.completion", DISPATCH_QUEUE_SERIAL);
int a[5] = {1, 2, 3, 4, 5};
average_async(a, 5, queue, ^(int average) {
NSLog(@"done, average = %d", average);
});
}
void average_async(int *data, size_t len,
dispatch_queue_t queue, void (^block)(int))
{
// Do the work on the default concurrent queue and then
// call the user-provided block with the results.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int avg = average(data, len);
dispatch_async(queue, ^{ block(avg);});
});
}
int average(int *data, size_t length) {
int sum = 0;
for (int i = 0; i< length; i++) {
sum += data[i];
}
return sum/length;
}
- 使用
dispatch_apply
来遍历
- (void)testApply {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
int count = 100;
dispatch_apply(count, queue, ^(size_t i) {
printf("%u\n",i);
});
}
- 使用信号量
//创建 count = 1
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
//wait, count--
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//do something
//临界区代码
//signal, count++
dispatch_semaphore_signal(semaphore); //count++
- 使用group
使用dispatch_group_wait
方式,会阻塞当前的线程,当group里的任务全部完成之后,当前线程继续执行
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
});
// Add another 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);
//all task done, continue to do other tasks
使用dispatch_group_notify
不阻塞当前的线程,group里的任务全部完成之后,会通知到对应的block去执行。
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
});
// Add another task to the group
dispatch_group_async(group, queue, ^{
// Some asynchronous work
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"all tasks are done");
});