iOS多线程技术的深度探究四: GCD多线程技术

/*
 GCD:
    同步方法:
        dispatch_sync:在当前线程执行任务,不会开启新的线程
        同步操作与队列无关
        同步方法会依次执行,能够控制任务的执行顺序
        更新UI时最好使用同步方法
        
    异步方法:
        dispatch_async:在其他线程执行任务,会开启新的线程
        异步方法无法控制任务的执行顺序
 
     全局(global)队列(可能开启多条线程)
     方法:dispatch_get_global_queue(获取全局队列)
     优先级:DISPATCH_QUEUE_PRIORITY_BACKGROUND
     所有任务并发(异步)执行
     
     串行队列(只能开启一条线程)
     方法:dispatch_queue_create(创建串行队列,不能获取)
     提示:队列名随意,不能使用@
     
     主队列
     方法:dispatch_get_main_queue(获取主队列)
     主线程队列
     
     在GCD中,同步还是异步,取决于任务执行所在的队列,跟方法名没有关系
 
 具体同步、异步与三个队列之间的关系,一定要反复测试体会!
    1.全局队列
        同步方法:在主线程中,依次执行
        异步方法:在新线程中,异步执行
    2.串行队列
        同步方法:在主线程中,依次执行
        异步方法:在新线程中,依次执行
    3.主队列
        同步方法:出错
        异步方法:在主线程中,依次执行
 */

#define SCREENWIDTH       [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT      [UIScreen mainScreen].bounds.size.height
#define W                 SCREENWIDTH/4
#define H                 (SCREENHEIGHT-50)/7
#define RANDOMDATA        (float)arc4random_uniform(256)/255

#import "ViewController.h"

@interface ViewController ()
{
    NSSet *viewSet;
}
@end

@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    [self setSubview];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)setSubview
{
    //实例化视图集合
    NSMutableSet *myViewSet = [NSMutableSet setWithCapacity:28];
    for (int row = 0; row < 7; row++) {
        for (int col = 0; col < 4; col++) {
            //计算view的位置
            int x = col * W;
            int y = row * H;
            
            UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, W, H)];
            view.backgroundColor = [UIColor colorWithRed:RANDOMDATA green:RANDOMDATA blue:RANDOMDATA alpha:1];
            [self.view addSubview:view];
            [myViewSet addObject:view];
        }
    }
    viewSet = myViewSet;
    
    //添加按钮
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setFrame:CGRectMake(0, SCREENHEIGHT-50, SCREENWIDTH/2, 50)];
    [button setBackgroundColor:[UIColor blackColor]];
    [button setTitle:@"刷新图片" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(didButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button1 setFrame:CGRectMake(SCREENWIDTH/2, SCREENHEIGHT-50, SCREENWIDTH/2, 50)];
    [button1 setBackgroundColor:[UIColor blackColor]];
    [button1 setTitle:@"线程顺序控制" forState:UIControlStateNormal];
    [button1 addTarget:self action:@selector(didButton1Clicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button1];
}

#pragma mark - 多线程:NSThread加载图片
- (IBAction)didButtonClicked:(id)sender
{
    NSLog(@"点击我!");
    [self gcdLoad];
}

- (IBAction)didButton1Clicked:(id)sender
{
    NSLog(@"点击我!");
    [self gcdDemo];
}

#pragma mark - CGD加载图像
- (void)gcdLoad
{
    /*
     全局(global)队列
        方法:dispatch_get_global_queue(获取全局队列)
        优先级:DISPATCH_QUEUE_PRIORITY_BACKGROUND
        所有任务并发(异步)执行
     主队列
        方法:dispatch_get_main_queue(获取主队列)
        主线程队列
     串行队列
     
     */
    //dispatch 派发
    //异步(async)执行,并发执行
    //优先级(priority),使用默认优先级即可
    
    //获取全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    for (UIView *view in viewSet) {
        dispatch_async(queue, ^{
            NSLog(@"GCD:%@",[NSThread currentThread]);
            //设置view,在主线程队列中设置UI
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"更新界面:%@",[NSThread currentThread]);
                view.backgroundColor = [UIColor colorWithRed:RANDOMDATA green:RANDOMDATA blue:RANDOMDATA alpha:1];
            });
        });
    }
}

- (void)gcdDemo
{
    /*
     全局(global)队列
     方法:dispatch_get_global_queue(获取全局队列)
     优先级:DISPATCH_QUEUE_PRIORITY_BACKGROUND
     所有任务并发(异步)执行
     
     串行队列
     方法:dispatch_queue_create(创建串行队列,不能获取)
     提示:队列名随意,不能使用@
     
     主队列
     方法:dispatch_get_main_queue(获取主队列)
     主线程队列
     
     在GCD中,同步还是异步,取决于任务执行所在的队列,跟方法名没有关系
     */
    //dispatch 派发
    //异步(async)执行,并发执行
    //优先级(priority),使用默认优先级即可
    
    //在全局队列中调用异步任务
    //1. 全局队列,是由系统负责的,开发时不需要考虑并发线程的数量问题
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    //串行队列,需要创建,不能get
    //DISPATCH_QUEUE_SERIAL串行队列
//    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    
    //主队列
//    dispatch_queue_t queue = dispatch_get_main_queue();
    
    //2. 在队列中执行异步方法任务
    dispatch_async(queue, ^{
        NSLog(@"异步任务1:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步任务2:%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"异步任务3:%@",[NSThread currentThread]);
    });
    
    // 在队列中执行同步方法任务
    dispatch_sync(queue, ^{
        NSLog(@"同步任务1:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步任务2:%@",[NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"同步任务3:%@",[NSThread currentThread]);
    });
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

你可能感兴趣的:(iOS多线程专辑)