iOS开发——多线程篇——NSThread
一、基本使用
1、创建和启动线程
一个NSThread对象就代表一条线程
创建、启动线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 线程一启动,就会在线程thread中执行self的run方法
主线程相关用法
+ (NSThread *)mainThread; // 获得主线程
- (BOOL)isMainThread; // 是否为主线程
+ (BOOL)isMainThread; // 是否为主线程
2、其他用法
获得当前线程
NSThread *current = [NSThread currentThread];
线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
3、其他创建线程方式
创建线程后自动启动线程(detach会自动分离(开启)一个新的线程, 并且自动调用start)
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
隐式创建并启动线程(Swift中不能使用, 苹果认为这个方法不安全)
[self performSelectorInBackground:@selector(run) withObject:nil];
上述2种创建线程方式的优缺点
优点:简单快捷
缺点:无法对线程进行更详细的设置
二、线程状态
1、线程状态

2、控制线程状态
启动线程
- (void)start;
// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
阻塞(暂停)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 进入阻塞状态
强制停止线程
+ (void)exit;
// 进入死亡状态
注意:一旦线程停止(死亡)了,就不能再次开启任务
一旦强行终止线程,后续的所有代码都不会被执行
注意:在终止线程之前,应该注意释放之前分配的对象!
三、安全隐患
1、多线程的安全隐患
资源共享
1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
比如多个线程访问同一个对象、同一个变量、同一个文件
当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题
解决方案

2、安全隐患解决 – 互斥锁
互斥锁使用格式
@synchronized(锁对象) { // 需要锁定的代码 }
注意:锁定1份代码只用1把锁,用多把锁是无效的
互斥锁的锁定范围,应该尽量小,锁定范围越大,效率越差!
如果代码中只有一个地方需要加锁,大多都使用 self
@synchronized(self) { // 需要锁定的代码 }
互斥锁的优缺点
优点:能有效防止因多线程抢夺资源造成的数据安全问题
缺点:需要消耗大量的CPU资源
互斥锁的使用前提:多条线程抢夺同一块资源
相关专业术语:线程同步
线程同步的意思是:多条线程在同一条线上执行(按顺序地执行任务)
互斥锁,就是使用了线程同步技术
3、自旋锁 & 互斥锁
-共同点
都能够保证同一时间,只有一条线程执行锁定范围的代码
-不同点
互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入"休眠"状态,等待其他线程执行完毕,打开锁之后,线程会被"唤醒"
自旋锁:如果发现有其他线程正在执行锁定的代码,线程会"一直等待"锁定代码执行完成!
自旋锁更适合执行非常短的代码!
- 无论什么锁,都是要付出代价的!
- 日常开发中,使用锁的机会很少,多线程的目的,就是将耗时的操作放在后台!
四、原子和非原子属性
1、属性
OC在定义属性时有nonatomic和atomic两种选择
atomic:原子属性,为setter方法加锁(默认就是atomic)
nonatomic:非原子属性,不会为setter方法加锁
2、原子和非原子属性的选择
nonatomic和atomic对比
atomic:原子属性(线程安全),就是针对多线程设计的,是默认属性
多个线程写入属性时,保证同一时间只有一个线程能够执行写入操作
nonatomic:非线程安全,适合内存小的移动设备
iOS开发的建议
所有属性都声明为nonatomic
尽量避免多线程抢夺同一块资源
尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力
五、线程间的通信

1、线程间通信
什么叫做线程间通信
在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
线程间通信的体现
1个线程传递数据给另1个线程
在1个线程中执行完特定任务后,转到另1个线程继续执行任务
线程间通信常用方法
参数:
waitUntilDone是否等待被调用方法执行完成,有可能也会等待调用方法的执行完成!
YES: 等待被调用线程执行完毕再执行后面的代码
NO : 不用等待被调用线程执行完毕就可以执行后面的代码
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
iOS开发——多线程篇——NSThread的更多相关文章
- iOS开发多线程篇—多线程简单介绍
iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...
- iOS开发多线程篇—线程安全
iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块 ...
- iOS 开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
- iOS开发多线程篇—创建线程
iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...
- iOS开发多线程篇—线程间的通信
iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...
- iOS开发多线程篇—GCD介绍
iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...
- iOS开发多线程篇—线程的状态
iOS开发多线程篇—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(te ...
- iOS开发多线程篇—GCD的基本使用
iOS开发多线程篇—GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进 ...
- iOS开发多线程篇—GCD的常见用法
iOS开发多线程篇—GCD的常见用法 一.延迟执行 1.介绍 iOS常见的延时执行有2种方式 (1)调用NSObject的方法 [self performSelector:@selector(run) ...
随机推荐
- OC之从键盘输入NSString字符串
方法一: char *a; static char z; a = &z; gets(a); NSString *intput = [NSString stringWithUTF8String: ...
- centos 7.0 ssh 登陆
CentOS 7.0 最小化安装 默认连接 默认端口是22 安装完查看IP 命令 ip addr ip: 192.168.1.103 自己家里练习的机子 都没改配置了 使用putty 远程连接 下载页 ...
- 【转】SPDY协议
SPDY协议 - v3 原文:SPDY Protocol - Draft 3 翻译:邱鹏滔(QQ: 95350530,主页:www.fireflysource.com) 1 概述 HTTP协议的瓶颈在 ...
- Java并发编程核心方法与框架-Semaphore的使用
Semaphore中文含义是信号.信号系统,这个类的主要作用就是限制线程并发数量.如果不限制线程并发数量,CPU资源很快就会被耗尽,每个线程执行的任务会相当缓慢,因为CPU要把时间片分配给不同的线程对 ...
- ES6新特性--多行文本
由于多行字符串用\n写起来比较费事,所以最新的ES6标准新增了一种多行字符串的表示方法,用` ... `表示: `这是一个 多行 字符串`;
- mysql中DATETIME,DATE和TIMESTAMP的区别整理
简而言之.看格式,DATE 是 年月日YYYY-MM-DD,DATETIME 是 年月日时分秒YYYY-MM-DD HH:MM:SS,TIMESTAMP是 年月日时分秒YYYY-MM-DD HH:MM ...
- Xcode常用技巧(2)-使Xcode在创建类时自动添加前缀
在Xcode5之前的版本中,Xcode在新建项目时,会要求为一个类指定一个前缀,这样方便我们区分相同名字的类.而从Xcode6开始,由于Swift增加了命名空间的关系,Xcode在新建项目时,不会再要 ...
- Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
- What is the most common software of data mining? (整理中)
What is the most common software of data mining? 1 Orange? 2 Weka? 3 Apache mahout? 4 Rapidminer? 5 ...
- 清北暑假模拟day1 爱
/* 水题 */ #include<iostream> #include<cstdio> #include<string> #include<cstring& ...