1 协程是一种比线程更轻量级的存在,如几个进程可以拥有多个线程一样,一个线程可以拥有多个协程.
2 线程的阻塞状态是由操作系统的内核进行切换的,而协程不是被操作系统内核管理,而是完全由程序控制,也就是在用户态执行,不需要像线程那样在用户态和内核态之间来回切换。所以,协程的开销会远远小于线程的开销。和多线程相比,线程的数量越多,协程的性能优势也就越明显

使用协程的优点:

  1. 协程不是被操作系统内核管理,是在用户态执行,所以节省了线程切换的性能开销
  2. 不需要多线程的锁机制

    使用协程的缺点:

  3. 我们需要自己承担协程之间调度的责任。

  4. 由于协程本质上是在单线程上跑的,也就失去了线程使用多 CPU 的能力,无法利用多核资源。只有将协程和进程配合才可以使用多 CPU。
  5. 在协程中如果使用了阻塞操作,会阻塞掉整个程序。

开篇我们先来看看coobjc的强大能力:

下面是一个下载图片并在主线程赋值的一个操作,是常规代码.

  1. [NSURLConnection sendAsynchronousRequest:rq queue:nil completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
  2. if (connectionError) {
  3. if (callback) {
  4. callback(nil, nil,connectionError);
  5. }
  6. }
  7. else{
  8. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  9. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  10. NSString *imageUrl = dict[@"image"];
  11. [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]] queue:nil completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
  12. dispatch_async(dispatch_get_global_queue(0, 0), ^{
  13. if (connectionError) {
  14. callback(nil, dict,connectionError);
  15. }
  16. else{
  17. UIImage *image = [[UIImage alloc] initWithData:data];
  18. if (callback) {
  19. (image, dict, nil);
  20. }
  21. }
  22. });
  23. }];
  24. });
  25. }
  26. }]

那么我们用协程可以多简单呢?废话不多说,上代码

  1. co_launch(^{
  2. NSData *data = await(downloadDataFromUrl(url));
  3. UIImage *image = await(imageFromData(data));
  4. self.imageView.image = image;
  5. });

三行代码,逻辑很清晰

在付呗项目中采用了大量coobjc结合rac使用的例子,结合我们项目的MVVM架构,对于项目解耦有很大帮助.

小结

coobjc为objc和swift提供了协程能力,以及基于协程的一些便捷的方法和编程范式。但对比Javascript/dart/go等原生支持协程的语言,这种hack的方式添加的语法毕竟不是特别友好。