NSThread

NSThread是一个苹果封装过的,面向对象的线程对象。但是它的生命周期需要我们自己来手动管理,所以使用不是很常见,比如[NSThread currentThread],它可以获取当前的线程类,你就可以知道当前线程的各种属性。

创建并启动

    //1.先创建,再启动
//创建
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
//启动
[thread start]; //2.创建并自动启动
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
//苹果认为performSelector系列方法不安全,所以在swift中,去掉了这个方法
[self performSelectorInBackground:@selector(run) withObject:nil];

NSThread其他常用的方法

    /*
//3.NSThread的常见方法
//取消线程
- (void)cancel;
//启动线程
- (void)start;
//判断某个线程的状态的属性
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isCancelled) BOOL cancelled;
//设置和获取线程名字
-(void)setName:(NSString *)n;
-(NSString *)name;
//获取当前线程信息
+ (NSThread *)currentThread;
//获取主线程信息
+ (NSThread *)mainThread;
//使当前线程暂停一段时间,或者暂停到某个时刻
+ (void)sleepForTimeInterval:(NSTimeInterval)time;
+ (void)sleepUntilDate:(NSDate *)date;
*/

GCD

Grand Central Dispatch,感觉很强大,当然,它的确很强大。它是苹果公司为多处理器的并行运算提出的解决方案,所以可以自动合理的利用跟多的cpu内核(不懂~~~),GCD可以自动的管理线程的生命周期(创建线程,调度任务,销毁线程),作为程序员,我们不需要管理线程的生命周期,我们只需要告诉GCD我们需要完成什么任务。GCD使用了很多的Block(闭包),所以使用起来也很方便,基本上GCD的使用是比较多的。

任务和队列

概念:

任务

  任务就是操作,你要完成什么任务,就是你要完成什么操作,也就是一段代码。这段代码可以写到GCD中的Block中,所以这样添加任务特别方便。

  任务有两种执行方式:同步执行和异步执行的主要区别是会不会阻塞当前线程,知道Block中的代码执行完毕。

如果是同步(sync)操作,它会阻塞当前线程并等待Block中的任务执行完毕,然后当前线程才能继续执行。

如果是异步(async)操作,当前线程会继续往下执行,它不会阻塞当前线程。

队列

  队列是用来存放任务的。队列分为两种,串行队列和并行队列。

  • 串行队列

  串行队列中的任务会根据队列的定义FIFO的执行,一个接一个的先进先出进行执行。放到串行队列中的任务,GCD会根据FIFO(先进先出)地取出来一个,执行一个,然后去下一个,执行下一个,这样一个接一个的执行。

  • 并行队列

  并行队列中的任务会根据同步和异步的不同有不同的执行方式。

并行队列 中的任务根据同步或异步有不同的执行方式。虽然很绕,但请看下表

在串行队列中执行同步任务:不会新建线程,按顺序执行任务(毫无用处)
在串行队列中执行异步任务,会新建线程,按顺序执行任务(非常有用)
在并行队列中执行同步任务:不会新建线程,按顺序执行任务(几乎没用)
在并行队列中执行异步任务:会新建多个线程,但是无法确定任务的执行顺序(有用,但是很容易出错)
 

创建队列和创建任务

 
    //GCD
//创建队列
//主队列,是一个特殊的串行队列,它用于刷新UI,如何需要刷新UI的工作都要在主队列中进行,所以一般耗时的任务都要放在别的线程中完成。
dispatch_queue_t queue = dispatch_get_main_queue(); //自己创建的队列:自己可以创建串行队列,也可以创建并行队列。其中第一个参数是标识符,用于DEBUG的时候标识唯一的队列,可以为空。第二个参数很重要,用来表示创建的队列是并行的还是串行的,传入DIS或者NULL表示创建了一个串行队列。传入DIS表示创建了一个并行队列。
dispatch_queue_t queue2 = dispatch_queue_create("dl.test.QueueTest2", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue3 = dispatch_queue_create("dl.test.QueueTest3", DISPATCH_QUEUE_CONCURRENT); //创建任务
//创建同步任务:不会另开线程(SYNC)
dispatch_sync(queue2, ^{
NSLog(@"%@",[NSThread currentThread]);
}); //异步任务:会另开线程(ASYNC)
dispatch_async(queue3, ^{
NSLog(@"%@",[NSThread currentThread]);
});

这里我们看两个例子,对于GCD中,同步任务的使用问题:

    NSLog(@"之前-%@", [NSThread currentThread]);

    dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"sync - %@", [NSThread currentThread]);
}); NSLog(@"之后-%@", [NSThread currentThread]); /*
分析:
1.打印完第一句后,dispatch_sync 就会立即阻塞当前的主线程,然后把block中的任务放到main_queue中,可是main_queue中的任务会被取出来放到主线程中执行,但是,主线程现在已经被dispatch_sync阻塞了,所以block中的代码就不能完成,不能完成,dispatch_sync就会一直阻塞主线程,造成死锁现象,导致主线程卡死。
*/

第二个例子

dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"之前-%@",[NSThread currentThread]);
dispatch_async(queue, ^{
NSLog(@"sync之前-%@",[NSThread currentThread]);
dispatch_sync(queue, ^{
NSLog(@"sync-%@",[NSThread currentThread]);
});
NSLog(@"sync之后-%@",[NSThread currentThread]);
});
NSLog(@"之后-%@",[NSThread currentThread]);
/*
分析:
1.首先创建一个叫做“myQueue”的串行队列。
2.打印当前线程
3.在myQueue的串行队列中添加异步任务(async),异步执行,不会阻塞当前线程,于是有了两条线程,一个线程继续打印“之后-%@”这句。另一个线程执行执行block中的内容,首先打印“sync之前-%@”
4.接下来,dispatch_sync是同步任务,它会阻塞当前所在线程,一直等到sync里的任务执行完成后才会继续往下。于是 sync 就高兴的把自己 Block 中的任务放到 queue 中,可谁想 queue 是一个串行队列,一次执行一个任务,所以 sync 的 Block 必须等到前一个任务执行完毕,可万万没想到的是 queue 正在执行的任务就是被 sync 阻塞了的那个。于是又发生了死锁。
*/

队列组

将很多的队列添加到一个组里,当组里的所有任务都执行完成后,队列组会调用方法通知我们。

    //1.创建队列组
dispatch_group_t group = dispatch_group_create();
//2.创建队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//3.多次使用队列组的方法执行任务,只有异步方法
//3.1 执行3次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = ; i < ; i++) {
NSLog(@"group-01 - %@", [NSThread currentThread]);
}
});
//3.2 主队列执行8次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = ; i < ; i++) {
NSLog(@"group-02 - %@", [NSThread currentThread]);
}
});
//3.3 执行5次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = ; i < ; i++) {
NSLog(@"group-03 - %@", [NSThread currentThread]);
}
});
//4.都执行完成后自动通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成 - %@", [NSThread currentThread]);
});

回到主线程

在其他线程中操作完成后,必须回到主线程中更新UI,下边代码是回到主线程的方法:

GCD

//Objective-C
dispatch_async(dispatch_get_main_queue(), ^{
});

iOS中的多线程基础的更多相关文章

  1. OS X 和iOS 中的多线程技术(上)

    OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...

  2. OS X 和iOS 中的多线程技术(下)

    OS X 和iOS 中的多线程技术(下) 上篇文章中介绍了 pthread 和 NSThread 两种多线程的方式,本文将继续介绍 GCD 和 NSOperation 这两种方式.. 1.GCD 1. ...

  3. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  4. iOS中的多线程 NSOperation

    在ios中,使用多线程有三种方式,分别是:NSThread.NSOperation和NSOperationQueue.GCD,在本节,主要讲解一下NSOperation的使用. NSOperation ...

  5. IOS中的多线程和NSRunLoop概述(转载)

    线程概述 有些程序是一条直线,从起点到终点,如Hello World,运行打印完,它的生命周期便结束了:有些程序是一个圆,不断循环,直到将它切断,如操作系统,一直运行直到你关机.  一个运行着的程序就 ...

  6. java中的多线程 // 基础

    java 中的多线程 简介 进程 : 指正在运行的程序,并具有一定的独立能力,即 当硬盘中的程序进入到内存中运行时,就变成了一个进程 线程 : 是进程中的一个执行单元,负责当前程序的执行.线程就是CP ...

  7. C#中的多线程 - 基础知识 z

    原文:http://www.albahari.com/threading/ 专题:C#中的多线程 1简介及概念Permalink C# 支持通过多线程并行执行代码,线程有其独立的执行路径,能够与其它线 ...

  8. iOS中的多线程NSThread/GCD/NSOperation & NSOperationQueue

    iOS多线程有四套多线程方案: Pthreads NSThread GCD NSOperation & NSOperationQueue 接下来我来一个一个介绍他们 Pthreads 在类Un ...

  9. C#中的多线程 - 基础知识

    原文:http://www.albahari.com/threading/ 文章来源:http://blog.gkarch.com/threading/part1.html 1简介及概念 C# 支持通 ...

随机推荐

  1. JavaScript 运动框架 Step by step(转)

    1,运动原理 Js运动,本质来说,就是让 web 上 DOM 元素动起来.而想要 DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等.动画的原理就是把不同状态的物体,串成连续的样 ...

  2. [妙味JS基础]JS热身运动

    知识点总结 获取ID元素 document.getElementById(' ') 事件:鼠标事件.键盘事件.系统事件.表单事件.自定义事件 onclick onmouseout onmouseove ...

  3. HDU_1245_Saving James Bond_最短路

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1245 题意:给一个已知直径的圆形岛,然后岛的附近是湖,湖里有一些点,以坐标的形式给出,最外层是矩形的终 ...

  4. 付款前.检查状态.防止重复付款,需要ajax设置为同步,等待ajax返回结果再使用

    $("#surePay").on("touchstart",function(){ var apply_id = $('#apply_id').val(); v ...

  5. [转]Ubuntu系统下常用的新建、删除、拷贝文件命令

    我们在Ubuntu系统中安装程序时,经常要在usr目录下新建.拷贝文件,此文件夹在Linux类系统中需要root权限才能访问,因此用常规的鼠标右键菜单操作是无效的,今天分享一下在终端中使用命令新建.拷 ...

  6. hdu 1407 测试你是否和LTC水平一样高

    Description 大家提到LTC都佩服的不行,不过,如果竞赛只有这一个题目,我敢保证你和他绝对在一个水平线上! 你的任务是: 计算方程x^2+y^2+z^2= num的一个正整数解.  Inpu ...

  7. WTL消息以及处理函数声明

    MSG_WM_CREATE LRESULT OnCreate(LPCREATESTRUCT lpCreateStruct); MSG_WM_INITDIALOG LRESULT OnInitDialo ...

  8. java的String类型为什么是final

    (转自:http://www.cnblogs.com/ikuman/archive/2013/08/27/3284410.html) 最佳答案: 主要是为了“效率” 和 “安全性” 的缘故.若 Str ...

  9. Ubuntu14.04下手动建立快捷方式

    先在桌面创建一个文件:文件内容如下 [Desktop Entry]Encoding=UTF-8Name=eclipseComment=eclipse ideExec=/home/mars/eclips ...

  10. 【code vs】 2780 ZZWYYQWZHZ

    2780 ZZWYYQWZHZ 题目描述 Description 可爱的小管在玩吹泡泡.忽然,他想到了一种排序....... 输入描述 Input Description 第一行输入n,表示有n个数. ...