GCD 例子

 

#import "ViewController.h"

 

@interface ViewController ()

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad

{

    [super viewDidLoad];

    

    NSLog(@"%@", [NSThread currentThread]);

    

    //[self gcdSyncDemo];

    [self gcdDemo4];

    

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    NSLog(@"Touch me");

}

 

#pragma mark - GCD方法

#pragma mark 同步任务的阻塞

- (void)gcdSyncDemo

{

    dispatch_queue_t q = dispatch_queue_create("cn.it.gcddemo", DISPATCH_QUEUE_SERIAL);

    

    // 任务嵌套

    dispatch_sync(q, ^{

        NSLog(@"sync %@", [NSThread currentThread]);

        

        // 耗时的任务,同步里面包含同步,会造成阻塞

//        dispatch_sync(q, ^{

        // 永远也不会执行到

//            NSLog(@"async %@", [NSThread currentThread]);

//        });

    });

}

 

#pragma mark - 主(线程)队列,保证操作在主线程上执行

- (void)gcdDemo4

{

    // 每一个应用程序都只有一个主线程

    // 为什么需要在主线程上工作呢?

    // 在iOS开发中,所有UI的更新工作,都必须在主线程上执行!

    dispatch_queue_t q = dispatch_get_main_queue();

    

    // 主线程是由工作的,而且除非将程序杀掉,否则主线程的工作永远不会结束!

    // 阻塞了!!!

    dispatch_sync(q, ^{

        NSLog(@"come here baby!");

    });

    

    // 异步任务,在主线程上运行,同时是保持队形的

    for (int i = 0; i < 10; ++i) {

        dispatch_async(q, ^{

            NSLog(@"%@ - %d", [NSThread currentThread], i);

        });

    }

}

 

#pragma mark - 全局队列(苹果为了方便多线程的设计,提供一个全局队列,供所有的APP共同使用)

- (void)gcdDemo3

{

    // 全局队列与并行队列的区别

    // 1> 不需要创建,直接GET就能用

    // 2> 两个队列的执行效果相同

    // 3> 全局队列没有名称,调试时,无法确认准确队列

    

    // 记住:在开发中永远用DISPATCH_QUEUE_PRIORITY_DEFAULT

    // 多线程的优先级反转!低优先级的线程阻塞了高优先级的线程!

    dispatch_queue_t q =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    

    for (int i = 0; i < 10; ++i) {

        // 同步任务顺序执行

        dispatch_sync(q, ^{

            NSLog(@"%@ %d", [NSThread currentThread], i);

        });

    }

    

    for (int i = 0; i < 10; ++i) {

        // 异步任务,并发执行,但是如果在穿行队列中,仍然会依次顺序执行

        dispatch_async(q, ^{

            // [NSThread currentThread] 可以在开发中,跟踪当前线程

            // num = 1,表示主线程

            // num = 2,表示第2个子线程。。。

            NSLog(@"%@ %d", [NSThread currentThread], i);

        });

    }

}

 

#pragma mark - 串行(一个接一个,排队跑步,保持队形)队列

- (void)gcdDemo1

{

    // 将操作放在队列中

    // 在C语言函数中,定义类型,绝大多数的结尾是_t或者ref

    // 使用串行队列,的异步任务非常非常非常有用!新建子线程是有开销的,不能无休止新建线程

    // 即可以保证效率(新建一个子线程),用能够实现并发

    // 应用案例:

    // 1> 从网络上上下载图片

    // 2> 滤镜(高光,红眼...)

    

    dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL);

    

    // 非ARC开发时,千万别忘记release

//    dispatch_release(q);

    

    // 串行行队列的同步任务,同样会在主线程上运行

    // 提示:在开发中极少用d

    for (int i = 0; i < 10; ++i) {

        // 同步任务顺序执行

        dispatch_sync(q, ^{

            NSLog(@"%@ %d", [NSThread currentThread], i);

        });

    }

    

    for (int i = 0; i < 10; ++i) {

        // 异步任务,并发执行,但是如果在串行队列中,仍然会依次顺序执行

        dispatch_async(q, ^{

            // [NSThread currentThread] 可以在开发中,跟踪当前线程

            // num = 1,表示主线程

            // num = 2,表示第2个子线程。。。

            NSLog(@"%@ %d", [NSThread currentThread], i);

        });

    }

}

 

#pragma mark - 并行(并排跑,类似于赛跑)

- (void)gcdDemo2

{

    // 特点:没有队形,执行顺序程序员不能控制!

    // 应用场景:并发执行任务,没有先后顺序关系

    // 并行队列容易出错!并行队列不能控制新建线程的数量!

    dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcd2", DISPATCH_QUEUE_CONCURRENT);

    

//    for (int i = 0; i < 10; ++i) {

//        // 异步任务

//        dispatch_async(q, ^{

//            // [NSThread currentThread] 可以在开发中,跟踪当前线程

//            // num = 1,表示主线程

//            // num = 2,表示第2个子线程。。。

//            NSLog(@"%@ %d", [NSThread currentThread], i);

//        });

//    }

    

    for (int i = 0; i < 10; ++i) {

        // 同步任务顺序执行

        dispatch_sync(q, ^{

            NSLog(@"%@ %d", [NSThread currentThread], i);

        });

    }

}

 

@end

//例子2----NSOperationQueue

import "ViewController.h"

 

@interface ViewController ()

 

@property (nonatomic, strong) NSOperationQueue *myQueue;

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.myQueue = [[NSOperationQueue alloc] init];

    

    [self demoOp1];

}

 

- (void)demoOp:(id)obj

{

    NSLog(@"%@ - %@", [NSThread currentThread], obj);

}

 

#pragma mark - NSOperation方法

#pragma mark 设置任务的执行顺序

- (void)demoOp3

{

    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"下载图片 %@", [NSThread currentThread]);

    }];

    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"修饰图片 %@", [NSThread currentThread]);

    }];

    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"保存图片 %@", [NSThread currentThread]);

    }];

    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"更新UI %@", [NSThread currentThread]);

    }];

    

    // 设定执行顺序, Dependency依赖,可能会开多个,但不会太多

    // 依赖关系是可以跨队列的!

    [op2 addDependency:op1];

    [op3 addDependency:op2];

    [op4 addDependency:op3];

    // GCD是串行队列,异步任务,只会开一个线程

    

    [self.myQueue addOperation:op1];

    [self.myQueue addOperation:op2];

    [self.myQueue addOperation:op3];

    // 所有UI的更新需要在主线程上进行

    [[NSOperationQueue mainQueue] addOperation:op4];

}

 

#pragma mark NSInvocationOP

- (void)demoOp2

{

    // 需要定义一个方法,能够接收一个参数

    // 是用起来不够灵活

    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demoOp:) object:@"hello op"];

    

//    [self.myQueue addOperation:op];

    

    [[NSOperationQueue mainQueue] addOperation:op];

}

 

#pragma mark NSBlockOperation

- (void)demoOp1

{

//    NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{

//        NSLog(@"%@", [NSThread currentThread]);

//    }];

//    

    // 所有的自定义队列,都是在子线程中运行

//    [self.myQueue addOperation:block];

    

    // 新建线程是有开销的

    // 在设定同时并发的最大线程数时,如果前一个线程工作完成,但是还没有销毁,会新建线程

    // 应用场景:网络开发中,下载工作!(线程开销:CPU,MEM)电量!

    // 如果是3G,开3个子线程

    // 如果是WIFI,开6个子线程

    

    for (int i = 0; i < 10; ++i) {

        [self.myQueue addOperationWithBlock:^{

            NSLog(@"%@ %d", [NSThread currentThread], i);

        }];

    }

    

    // 在主线程中执行

//    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

//        NSLog(@"%@", [NSThread currentThread]);

//    }];

}

 

@end

// GCD 线程例2

 

#import "MViewController.h"

 

 

 

@interface MViewController ()

 

 

 

@end

 

 

 

@implementation MViewController

 

/**

 

 

 

 GCD的任务

 

 

 

 1> disptach_sync       没有创建线程的欲望,就在当前线程执行

 

    最主要的目的,阻塞并行队列任务的执行,只有当前的同步任务执行完毕后,后续的任务才能够执行

 

    应用场景:用户登录!

 

 

 

 2> dispatch_async      有创建线程的欲望,但是创建多少条线程,取决与队列的类型

 

 

 

 GCD的队列

 

 

 

 1> 串行队列              类似于跑步,只有一条跑道,最多能够有两条

 

    如果存在异步任务,就会在新线程中执行异步任务,而同步任务依旧在当前线程中执行

 

 

 

 2> 并行队列              类似与赛跑,具体跑道的数量,由系统决定

 

 */

 

 

 

- (void)viewDidLoad

 

{

 

    [super viewDidLoad];

 

    

 

    [self demo];

 

}

 

 

 

- (void)demo

 

{

 

    dispatch_queue_t q = dispatch_queue_create("demo", DISPATCH_QUEUE_CONCURRENT);

 

    

 

    // 在新线程中工作

 

    dispatch_async(q, ^{

 

        // 2

 

        NSLog(@"%@", [NSThread currentThread]);

 

        

 

        __block BOOL userLogon = NO;

 

        

 

        // 用户登录,用户输入用户名,密码之后,提交到服务器确认身份

 

        // 应用场景1:用来阻塞必须要按照顺序执行的任务

 

        dispatch_sync(q, ^{

 

            // 2

 

            NSLog(@"用户网络登陆 %@", [NSThread currentThread]);

 

            

 

            [NSThread sleepForTimeInterval:3.0f];

 

            

 

            userLogon = NO;

 

        });

 

        

 

        // 身份确认之前,不能做其他事情

 

        dispatch_async(q, ^{

 

            // 可能是3,也可能是2

 

            // 3.0(对的) / 立马执行(不对的)

 

            NSLog(@"后续处理 %@", [NSThread currentThread]);

 

            

 

            if (userLogon) {

 

                NSLog(@"welcome");

 

            } else {

 

                NSLog(@"why");

 

            }

 

        });

 

        

 

        // 队列是先进先出FIFO的,队列中的任务都是串着的

 

    });

 

}

 

posted @ 2016-03-29 21:48  lance.xiang  阅读(138)  评论(0编辑  收藏  举报