iOS开发-GCD常用函数和其他用法

2018-11-12  本文已影响0人  iOS_ZZ

今天给同学书写上文GCD(Grand Central Dispatch) 来实现多线程的技术常用的函数和一些用法那么废话不多说直接上代码~

//
//  ZZGCDViewController.m
//  8-多线程技术
//
//  Created by Jordan zhou on 2018/11/5.
//  Copyright © 2018年 Jordan zhou. All rights reserved.
//

#import "ZZGCDViewController.h"

@interface ZZGCDViewController ()
/** 图片1 */
@property (nonatomic, strong) UIImage *image1;
/** 图片2 */
@property (nonatomic, strong) UIImage *image2;
@end

@implementation ZZGCDViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self barrier];
}

/**
 *  栅栏
 */
- (void)barrier
{
    dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"----1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----2-----%@", [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"----3-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----4-----%@", [NSThread currentThread]);
    });
}

/**
 *  延迟执行
 */
- (void)delay
{
    [self performSelector:@selector(onceToken) withObject:nil afterDelay:2.0f];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self onceToken];
    });
    
    [NSTimer scheduledTimerWithTimeInterval:2.0f repeats:NO block:^(NSTimer * _Nonnull timer) {
        [self onceToken];
    }];
    
    [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(onceToken) userInfo:nil repeats:NO];
}

/**
 *  一次性
 */
- (void)onceToken
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"onceToken----run");
    });
}

/**
 * 快速迭代
 */
- (void)apply
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    NSString *from = @"/Users/zhouzhao/Desktop/From";
    NSString *to = @"/Users/zhouzhao/Desktop/To";
    
    NSFileManager *mgr = [NSFileManager defaultManager];
    NSArray *subpaths = [mgr subpathsAtPath:from];
    
    dispatch_apply(subpaths.count, queue, ^(size_t index) {
        NSString *subpath = subpaths[index];
        NSString *fromFullpath = [from stringByAppendingPathComponent:subpath];
        NSString *toFullpath = [to stringByAppendingPathComponent:subpath];
        
        // 剪切
        [mgr moveItemAtPath:fromFullpath toPath:toFullpath error:nil];
        
#warning - 有的主线程中进行有的则在子线程中进行
        NSLog(@"%@---%@", [NSThread currentThread], subpath);
    });
}

/**
 * 传统文件剪切
 */
- (void)moveFile
{
    NSString *from = @"/Users/zhouzhao/Desktop/From";
    NSString *to = @"/Users/zhouzhao/Desktop/To";
    
    NSFileManager *mgr = [NSFileManager defaultManager];
    NSArray *subpaths = [mgr subpathsAtPath:from];
    
    for (NSString *subpath in subpaths) {
        NSString *fromFullpath = [from stringByAppendingPathComponent:subpath];
        NSString *toFullpath = [to stringByAppendingPathComponent:subpath];
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 剪切
            [mgr moveItemAtPath:fromFullpath toPath:toFullpath error:nil];
            
            NSLog(@"%@---%@", [NSThread currentThread], subpath);
        });
    }
}

/**
 *  队列组
 */
- (void)gcdGroup
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 创建一个队列组
    dispatch_group_t group = dispatch_group_create();
    
    // 1.下载图片1
    dispatch_group_async(group, queue, ^{
        // 图片的网络路径
        NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"];
        
        // 加载图片
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        // 生成图片
        self.image1 = [UIImage imageWithData:data];
    });
    
    // 2.下载图片2
    dispatch_group_async(group, queue, ^{
        // 图片的网络路径
        NSURL *url = [NSURL URLWithString:@"http://pic38.nipic.com/20140228/5571398_215900721128_2.jpg"];
        
        // 加载图片
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        // 生成图片
        self.image2 = [UIImage imageWithData:data];
    });
    
#pragma mark - dispatch_group_notify 会等上面的任务执行完然后再执行这里
    
    // 3.将图片1、图片2合成一张新的图片
    dispatch_group_notify(group, queue, ^{
        // 开启新的图层上下文
        UIGraphicsBeginImageContext(CGSizeMake(100, 100));
        
        // 绘制图片
        [self.image1 drawInRect:CGRectMake(0, 0, 50, 100)];
        [self.image2 drawInRect:CGRectMake(50, 0, 50, 100)];
        
        // 取得上下文中的图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        
        // 结束上下文
        UIGraphicsEndImageContext();
        
        // 回到主线程显示图片
        dispatch_sync(queue, ^{
            // 显示图片
        });
    });
}

/**
 *  gcd通过block和c语言实现s
 */
- (void)gcdC
{
//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
//    dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
//    dispatch_sync_f(<#dispatch_queue_t  _Nonnull queue#>, NULL, download)
}

void download(void *data)
{
    
}

/**
 *  gcd实现下载图片完成线程间的通信
 */
- (void)gcdDownload
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 图片的网络路径
        NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"];
        
        // 加载图片
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        // 生成图片
        UIImage *image = [UIImage imageWithData:data];
        
        // 回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            // 设置图片
            
        });
    });
}

/**
 * 同步函数 + 主队列:
 */
- (void)syncMain
{
    NSLog(@"syncMain ----- begin");
    
    // 1.获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.将任务加入队列
    dispatch_sync(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });

#pragma mark - 会造成线程的堵塞 不会有log打印
    NSLog(@"syncMain ----- end");
}

/**
 * 异步函数 + 主队列:只在主线程中执行任务
 */
- (void)asyncMain
{
    // 1.获得主队列
    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]);
    });
}

/**
 * 同步函数 + 串行队列:不会开启新的线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务
 */
- (void)syncSerial
{
    // 1.创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("jordan.zhou.com", DISPATCH_QUEUE_SERIAL);
    
    // 2.将任务加入队列
    dispatch_sync(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });
}

/**
 * 异步函数 + 串行队列:会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务
 */
- (void)asyncSerial
{
    // 1.创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("jordan.zhou.com", DISPATCH_QUEUE_SERIAL);
    //    dispatch_queue_t queue = dispatch_queue_create("jordan.zhou.com", NULL);
    
    // 2.将任务加入队列
    dispatch_async(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });
}

/**
 *  同步函数 + 并发队列:不会开启新的线程
 */
- (void)syncConcurrent
{
    // 1.获取全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.将任务加入队列
    dispatch_sync(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });

#pragma mark - 在当前线程执行 最后打印log
    NSLog(@"syncConcurrent--------end");
}

/**
 *  异步函数 + 并发队列:可以同时开启多条线程
 */
- (void)asyncConcurrent
{
    // 1.0创建一个并发队列
    // label : 相当于队列的名字
//    dispatch_queue_t queue = dispatch_queue_create("jordan.zhou.queue", DISPATCH_QUEUE_CONCURRENT);
    
    // 1.1获取全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.将任务加入队列
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 10; i++) {
            NSLog(@"1----%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 10; i++) {
            NSLog(@"2----%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i < 10; i++) {
            NSLog(@"3----%@",[NSThread currentThread]);
        }
    });
    
#pragma mark - 会先执行完下面的log然后再执行上面的任务
    NSLog(@"asyncConcurrent--------end");
}
@end

上一篇下一篇

猜你喜欢

热点阅读