为什么80%的码农都做不了架构师?>>>   

线程创建有三种方法:使用NSThread创建、使用GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject: afterDelay: 或者使用GCD的函数:

1、常用的方法dispatch_async

为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。

用GCD实现这个流程的操作比前面介绍的NSThread  NSOperation的方法都要简单。代码框架结构如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  // 耗时的操作  dispatch_async(dispatch_get_main_queue(), ^{  // 更新界面  });
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];  NSData * data = [[NSData alloc]initWithContentsOfURL:url];  UIImage *image = [[UIImage alloc]initWithData:data];  if (data != nil) {  dispatch_async(dispatch_get_main_queue(), ^{  self.imageView.image = image;  });  }
});

是不是代码比NSThread  NSOperation简洁很多,而且GCD会自动根据任务在多核处理器上分配资源,优化程序。

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

这里也用到了系统默认就有一个串行队列main_queue

dispatch_queue_t mainQ = dispatch_get_main_queue();

虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。

2、dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。下面是一段例子代码:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{  [NSThread sleepForTimeInterval:1];  NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{  [NSThread sleepForTimeInterval:2];  NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{  [NSThread sleepForTimeInterval:3];  NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{  NSLog(@"updateUi");
});
dispatch_release(group);

dispatch_group_async是异步的方法,运行后可以看到打印结果:

2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

每个一秒打印一个,当第三个任务执行后,upadteUi被打印。

3、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

例子代码如下:

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{  [NSThread sleepForTimeInterval:2];  NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{  [NSThread sleepForTimeInterval:4];  NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{  NSLog(@"dispatch_barrier_async");  [NSThread sleepForTimeInterval:4];  });
dispatch_async(queue, ^{  [NSThread sleepForTimeInterval:1];  NSLog(@"dispatch_async3");
});

打印结果:

2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2

2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async

2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

请注意执行的时间,可以看到执行的顺序如上所述。

4、dispatch_apply

执行某个代码片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
    // 执行5次

});

5、dispatch_after

//2秒后异步执行这里的代码...

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

});

转载于:https://my.oschina.net/aprill/blog/545917

Object C中创建线程的方法有NSThread,GCD, NSOperation相关推荐

  1. Linux设备驱动程序中创建线程的方法

    参考博客文章来源:https://blog.csdn.net/ezimu/article/details/60467017 第一种方法:kernel_thread #include <linux ...

  2. JAVA中创建线程的三种方法及比较

    JAVA中创建线程的方式有三种,各有优缺点,具体如下: 目录 一.继承Thread类来创建线程 二.实现Runnable接口来创建线程 三.通过Callable和Future来创建线程 四.三种方式创 ...

  3. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  4. java中创建线程的四种方式及线程池详解

    众所周知,我们在创建线程时有四种方法可以用,分别是: 1.继承Thread类创建线程 2.实现Runnable接口创建线程 3.使用Callable和Future创建线程 4.使用线程池创建(使用ja ...

  5. 陈硕智能指针线程安全_C++ 创建线程的方法

    C++开发过程中,创建线程是必不可少的,今天就给大家说说c++创建线程的方法,主要介绍我常用的2种方法. 第一种:CreateThread HANDLE WINAPI CreateThread( t ...

  6. Object类中的两个方法——wait和notify使用总结

    Object类中的wait .和 notify方法是用来处理线程的方法,既然定义在Object类中,两个方法的重要程度可见一斑: 两个方法的使用上都很复杂:通过阅读API获得更多对方法的理解: The ...

  7. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

    java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...

  8. Java中创建线程的三种方式

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...

  9. windows系统中创建线程常用哪几个函数,有什么区别?

    windows系统中创建线程常用哪几个函数? 在windows系统中创建线程的函数有: CreadThread,AfxBeginThread,_beginthread,_beginthreadex. ...

  10. Java-线程-创建线程的方法

    public class ThreadMain {/*** @param args*/public static void main(String[] args) {/*** 创建thread的子类, ...

最新文章

  1. think in Java 第五章之垃圾回收类型
  2. 使用Redis来实现LBS的应用
  3. c语言学习笔记-if语句块一定要加分号
  4. 【Java源码分析】LinkedList源码分析
  5. vuepress 2.x 集成 element-plus
  6. SQL SERVER数据库多条件查询
  7. js 短信验证码 6位数字
  8. 欧拉:他停止了生命和计算
  9. html5酷炫表白代码_七夕表白代码,樱花特效+爱心特效+花瓣+评论留言功能等
  10. phpstorm2017破解方法
  11. ERP系统之JPJDE入门-1 JDE 简史
  12. 可道云访问服务器其他文件,可道云怎么用_可道云使用功能解析
  13. 1.8 收集的XSS Payload
  14. 用Python爬取微信好友头像,才知道好友都是这样的人
  15. 华为matebook鸿蒙,16寸专业大屏+满血Zen3!华为MateBook 16评测:鸿蒙加持 平板变身新外设...
  16. webpack 打包错误
  17. 【PPic】基于Electron+Vue+iView的图床应用设计
  18. 超级课程表导入课程显示服务器繁忙,超级课程表 导入不了课表怎么办详解导入课程表教程...
  19. 一小时快速上手win10 docker 、vscode、MobaXterm、git协作开发
  20. 青云科技以开放姿态打造低代码平台

热门文章

  1. cocos2d 帧序列动画
  2. 【Android进阶】SlidingMenu实现侧滑栏效果的实现
  3. Safe3通用远程溢出漏洞扫描系统
  4. GitHub更新已经fork的项目
  5. 在url中传递参数(方法二)
  6. SQL拼接自己需要的字符串
  7. django 模型-----模型查询
  8. Redis学习笔记~关于空间换时间的查询案例
  9. 动态修改php的配置项
  10. 企业应用打包的时候 修改ipa包的bundle identifier