编程iOS开发专题IT

iOS 多线程 必谈之GCD

2016-05-19  本文已影响888人  不误正业的开发者

GCD (Grand Gentral Dispatch):存在于libdispatch 中,是一套基于C的API,函数功能灰常强大

一、dispatch queue

// 创建并发队列
dispatch_queue_t queue1 = dispatch_queue_create("com.JY", DISPATCH_QUEUE_CONCURRENT);
// 获取全局并发队列
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
```

// 手动创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.JY", DISPATCH_QUEUE_SERIAL);
```

// 获取当前主队列
dispatch_queue_t queue1 = dispatch_get_main_queue();
```

// 此处的queue为队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
// 需要执行的任务
NSLog(@"---------%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"---------%@", [NSThread currentThread]);
});
```

全局并发队列 创串行队列 主队列
同步(sync) 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务
异步(async) 开启新线程,并发执行任务 开启新线程,串行执行任务 没有开启新线程,串行执行任务

二、线程间的通信

// 图片的网络路径
NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=db9486a9d639b60059c307e588395e4f/b90e7bec54e736d1e174094298504fc2d5626911.jpg"];
// 显示图片
        
// 主线程刷新
   dispatch_async(dispatch_get_main_queue(), ^{
            
          self.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        });
    });

三、延时执行 dispatch_after:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"run-----");
        });

四、栅栏 dispatch_barrier_async

- (void)barrier
{
    dispatch_queue_t queue = dispatch_queue_create("com.JY", 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]);
    });
}

五、once

六、group dispatch_group_t (分组)

- (void)group
{
    
    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];
    });
    
    // 3.将图片1、图片2合成一张新的图片
    dispatch_group_notify(group, queue, ^{
        // 开启新的图形上下文
        UIGraphicsBeginImageContext(CGSizeMake(250, 250));
        
        // 绘制图片
        [self.image1 drawInRect:CGRectMake(0, 0, 125, 250)];
        [self.image2 drawInRect:CGRectMake(125, 0, 125, 250)];
        
        // 取得上下文中的图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        
        // 结束上下文
        UIGraphicsEndImageContext();
        
        // 回到主线程显示图片
        dispatch_async(dispatch_get_main_queue(), ^{
            // 4.将新图片显示出来
            self.imageView.image = image;
        });
    });
}

六、applay (快速迭代)

- (void)apply
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 源路径
    NSString *from = @"";
    // 目标路径
    NSString *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];
        
        NSLog(@"%@---%@", [NSThread currentThread], subpath);
    });
}
   NSString *from = @"";
    NSString *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];
        });
    }

七、GCD 计时器

// 说好的是OC 类为啥timer不带* 呢,因为dispatch_source_t 自带*
@property (nonatomic, strong) dispatch_source_t timer;
// 获得队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    // 创建定时器dispatch_source_create(dispatch_source_t本质还是个OC对象)
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//    NSLog(@"%@", self.timer);
    
    // 设置定时器的各种属性
    dispatch_source_set_timer(self.timer, dispatch_time(DISPATCH_TIME_NOW, 4.0 * NSEC_PER_SEC), 2.0 * NSEC_PER_SEC, 0);
    
    // 设置回调
    dispatch_source_set_event_handler(self.timer, ^{
        NSLog(@"JY is running");
        
    });
    // 启动定时器
    dispatch_resume(self.timer);
dispatch_cancel(self.timer);
上一篇 下一篇

猜你喜欢

热点阅读