美文网首页
Dispatch Queue

Dispatch Queue

作者: yxibng | 来源:发表于2018-12-23 19:55 被阅读0次

queue types

  • Serial
  • Concurrent
  • Main dispatch queue

Queue-Related Technologies

  • Dispatch groups
  • Dispatch semaphores
  • Dispatch sources
  1. 全局队列(Concurrent)

可选的优先级:

//参数1:队列优先级
//参数2:保留字段,传 0
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  1. 创建队列
//参数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);
  1. 运行时获取队列
    dispatch_get_current_queue
  2. 内存管理

Dispatch queues and other dispatch objects are reference-counted data types.
也是一种引用技术的类型

MRC下管理内存使用:

  1. 设置和获取队列上下文数据

创建队列上下文,并提供清理函数,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);
}
  1. 任务完成时,执行一个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;
}

  1. 使用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);
    });
}
  1. 使用信号量
//创建 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++
  1. 使用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");
});

相关文章

网友评论

      本文标题:Dispatch Queue

      本文链接:https://www.haomeiwen.com/subject/iqbnkqtx.html