GCD 和NSOperationQueue

2018-09-09  本文已影响0人  BangRaJun

同步异步、并行串行的区分


- (void)viewDidLoad {

    [super viewDidLoad];



    dispatch_queue_t queue = dispatch_queue_create("LivyNN", DISPATCH_QUEUE_SERIAL);

    NSArray *array = [[NSArray alloc] initWithObjects:@"liwei", nil];

    void *p = (__bridge void*)array;

    dispatch_async_f(queue, p, sumAB);

}

void sumAB(void *input){

    id object = (__bridge id)input;

    [NSThread sleepForTimeInterval:3];

    NSLog(@"%@", object);

    NSLog(@"线程结束");

}


- (void)viewDidLoad {

    [super viewDidLoad];



    dispatch_queue_t queue = dispatch_queue_create("LivyNN", DISPATCH_QUEUE_SERIAL);

    NSArray *array = [[NSArray alloc] initWithObjects:@"liwei", nil];

    void *p = (__bridge void*)array;

    dispatch_sync_f(queue, p, sumAB);//修改了这里async->sync

}

void sumAB(void *input){

    id object = (__bridge id)input;

    [NSThread sleepForTimeInterval:3];

    NSLog(@"%@", object);

    NSLog(@"线程结束");

}


- (void)viewDidLoad {

    [super viewDidLoad];



    dispatch_queue_t queue = dispatch_queue_create("LivyNN", DISPATCH_QUEUE_SERIAL);

    NSArray *array = [[NSArray alloc] initWithObjects:@"liwei", nil];

    void *p = (__bridge_retained void*)array;//retain

    dispatch_async_f(queue, p, sumAB);

}

void sumAB(void *input){

    id object = (__bridge_transfer id)input;//transfer

    [NSThread sleepForTimeInterval:3];

    NSLog(@"%@", object);

    NSLog(@"线程结束");

}


- (void)viewDidLoad {

    [super viewDidLoad];

    dispatch_queue_t queue = dispatch_queue_create("LivyNN", DISPATCH_QUEUE_SERIAL);//serial是串行

    NSArray *array = [[NSArray alloc] initWithObjects:@"liwei", nil];

    void *p = (__bridge_retained void*)array;//retain

    dispatch_async_f(queue, p, sumAB);

    dispatch_async_f(queue, p, sumAB);

}

void sumAB(void *input){

    id object = (__bridge_transfer id)input;//transfer

    [NSThread sleepForTimeInterval:3];

    NSLog(@"%@", object);

    NSLog(@"任务结束");

}


- (void)viewDidLoad {

    [super viewDidLoad];

    dispatch_queue_t queue = dispatch_queue_create("LivyNN", DISPATCH_QUEUE_ConCurrent);//concurrent并行

    NSArray *array = [[NSArray alloc] initWithObjects:@"liwei", nil];

    void *p = (__bridge_retained void*)array;//retain

    dispatch_async_f(queue, p, sumAB);

    dispatch_async_f(queue, p, sumAB);

}

void sumAB(void *input){

    id object = (__bridge_transfer id)input;//transfer

    [NSThread sleepForTimeInterval:3];

    NSLog(@"%@", object);

    NSLog(@"任务结束");

}

GCD

*创建一个线程:dispatch_queue_t queue = dispatch_queue_create("一个线程的名字,在调试的时候可以看到这个名字",DISPATCH_QUEUE_ConCurrent/DISPATCH_QUEUE_SERIAL);c是并行,s是串行。

*dispatch_async

*dispatch_async_f

*dispatch_sync

*dispatch_sync_f


    dispatch_async(queue, ^{

        /*异步添加block*/

    });

    dispatch_async_f(queue, p, sumAB);//队列,参数,函数 



dispatch_sync(queue, ^{

        /*同步添加block*/

    });

    dispatch_sync_f(queue, p, sumAB);//队列,参数,函数,注意函数要定义成C语言的形状,p需要是void*类型的地址,如果需要传id类型,则需要__bridge关键字转化,int类型参数可以直接int a = 0;&a


dispatch_queue_t mainQueue = dispatch_get_main_queue();


dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

*其中:DISPATCH_QUEUE_PRIORITY_LOW是个枚举,有:HIGH,DEFAULT,LOW,BACKGROUND,分别对应于2,0,-2,MIN四个数字。

注意注意:不能往主线程上加同步任务!!!不能往主线程上加同步任务!!!不能往主线程上加同步任务!!!

*并行循环迭代:dispatch_apply:


    dispatch_queue_t concurrentQueue = dispatch_queue_create("livyNNTest", DISPATCH_QUEUE_CONCURRENT);

    dispatch_apply(100, concurrentQueue, ^(size_t size) {

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"complete");

    });

*队列挂起:dispatch_suspend(queue);当前正在执行的任务不会中断

*队列恢复:dispatch_resume(queue);


    dispatch_queue_t queue = dispatch_queue_create("liwei", DISPATCH_QUEUE_CONCURRENT);

    dispatch_semaphore_t signal = dispatch_semaphore_create(3);//创建信号量,初始有三个

    dispatch_apply(100, queue, ^(size_t i) {

        dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);//如果有可用的信号量就直接返回,如果没有就在这等

        [NSThread sleepForTimeInterval:1];

        NSLog(@"%d",i);

        dispatch_semaphore_signal(signal);//运行完了释放信号量以循环使用

    });

*创建分组:dispatch_group_t group = dispatch_group_create();

*把任务放进分组:dispatch_group_async/synx(group,queue,^{任务})

*等待分组内任务全部完成:dispatch_group_wait(group,FOREVER);第二个参数是最大等待时间,等不到就不阻塞了。

*示例:


    dispatch_queue_t queue = dispatch_queue_create("liwei", DISPATCH_QUEUE_CONCURRENT);

    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, queue, ^{

        [NSThread sleepForTimeInterval:1.0];

        NSLog(@"第一个任务完成了");

    });

    dispatch_group_async(group, queue, ^{

        [NSThread sleepForTimeInterval:3.0];

        NSLog(@"第二个任务执行完了");

    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{

        NSLog(@"分组中的任务都执行完了");

    });

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

NSOperationQueue

*NSOperationQueue是基于GCD的封装。


NSOperationQueue *queue = [[NSOperationQueue alloc] init];

NSOperationQueue *queue = [NSOperationQueue mainQueue];

*添加block任务,相当于dispatch_async(queue,block):


[queue addOperationWithBlock:^{



}];


//block任务

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{



    }];

    [queue addOperation:blockOperation];

//invocation任务

    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperationMethod) object:nil];

    [queue addOperation:invocationOperation];

 //子类化NSOperation,覆盖其main方法,得子类SubOperation

 SubOperation *subOperation = [[SubOperation alloc] initWith::::];

 [queue addOperation:subOperation]; 

 //添加一组

     NSArray *operationArray = @[blockOperation,invocationOperation];

    [queue addOperations:operationArray waitUntilFinished:NO]; //NO相当于async,yes相当于sync


[blockOperation addDependency:invocationOperation];


    [blockOperation addDependency:invocationOperation];

    [queue addOperation:invocationOperation];

    [mainQueue addOperation:blockOperation];

*Operation优先级,代码如下:


NSBlockOperation *blockOperation0 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOperation0");

    }];

    NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOperation1");

    }];

    NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOperation2");

    }];

    NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOperation3");

    }];

    NSBlockOperation *blockOperation4 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOperation4");

    }];

    blockOperation0.queuePriority = NSOperationQueuePriorityVeryLow;

    blockOperation1.queuePriority = NSOperationQueuePriorityLow;

    blockOperation2.queuePriority = NSOperationQueuePriorityNormal;

    blockOperation3.queuePriority = NSOperationQueuePriorityHigh;

    blockOperation4.queuePriority = NSOperationQueuePriorityVeryHigh;

    NSArray *operationArray = @[blockOperation1,blockOperation3,blockOperation2,blockOperation0,blockOperation4];

    [queue addOperations:operationArray waitUntilFinished:NO];


queue.maxConcurrentOperationCount = 1;


queue.maxConcurrentOperationCount = 2;


queue.maxConcurrentOperationCount = 3;


queue.maxConcurrentOperationCount = MAX;

GCD唯一的有点就是速度快

NSOperationQueue有更多的依赖,优先级功能,且封装性更好。

结束

上一篇下一篇

猜你喜欢

热点阅读