博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS多线程学习二:NSThread
阅读量:3730 次
发布时间:2019-05-22

本文共 2380 字,大约阅读时间需要 7 分钟。

文章目录

一.NSThread 线程创建方式

selector后为线程调用的方法,object后为传入线程方法的参数类

NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@“abc”];

需要调[thread start];

//从主线程中分离一个子线程去执行任务,无需手动开启,分离出来后会立即启动

[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@“miss”];

//开一个后台线程,无需手动启动

[self performSelectorInBackground:@selector(run:) withObject:@“back”];

//把耗时操作放在子线程的方法中执行,防止界面卡顿

-(void)run:(id)obj{}

获取当前线程[NSThread currentThread];

获取主线程[NSThread mainThread];

二.线程状态

1.新建线程,alloc,开辟一段内存空间放置线程对象

2.开启线程,start,线程对象会被放置到对应的线程池中。就绪状态,等待CPU调度。
3.当CPU调度该线程时,运行状态。
4.当CPU调度其他线程的时候,返回就绪状态。
5.当调用了sleep/等待同步锁,进入阻塞状态(blocked),线程对象从线程池中移出来;当sleep到时/等到了同步锁,线程进入就绪状态,线程对象回归到线程池中,等待CPU调度。
6.线程的死亡,线程任务执行完成,自动死亡;线程异常/强制退出。
一旦线程死亡,线程对象从内存中移除,不能再重新开启,如果尝试重新开启线程,程序会挂掉。

线程休眠

第一种方法

[NSThread sleepForTimeInterval:2];

第二种方法

[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];

如果想线程任务执行一部分之后永远不要开启

[NSThread sleepUntilDate:[NSDate distantFuture]];//在遥远的未来

线程强制退出

[NSThread exit] ;

三.线程安全隐患

一块资源可能会被多个线程共享,即多个线程同时访问操作同一个数据(对象,变量,文件)(线程并发执行),很容易引发数据错乱和数据安全问题。

解决方案:使用线程同步技术(按先后顺序执行),常用技术是加锁。

@synchronized

互斥锁的优点:有效防止因多线程抢夺资源造成的数据安全问题。

缺点:因为线程等待,需要消耗大量的CPU资源。
注意:互斥锁又叫线程同步。
线程同步:多条线程在同一条线上执行,按顺序执行任务。
@synchronized(self) 创建一个互斥锁,保证此时没有其他线程对self对象进行修改
@synchronized(锁对象){//需要锁定的代码}
锁对象是同一个,是唯一的。

在这里插入图片描述

四.线程通信

在一个进程中,线程往往不是孤立存在的,多个线程之间是存在有通信关系的。

体现:
1.一个线程传递数据给另一个线程
2.一个线程执行完成任务后转到另外一个线程继续执行任务。
eg:在子线程中做耗时操作加载网络图片,然后回到主线程显示网络图片。
self.imageView.image=[UIImage imageNamed: name];添加的图片是在工程内部的图片。
从网络下载的图片用self.imageView.image=[UIImage imageWithData: data];

NSURL *url=[NSURL URLWithString:IMAGE_URL];

NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:data];

注意:xcode7以后如果想要使用http协议,需要在Info.plist里面添加字段. App Transport Security settings / Allow Arbitrary Loads YES

//查看代码的执行时间
NSDate *begin=[NSDate date];
代码
NSDate *end=[NSDate date];
NSLog(@"%f",[end timeIntervalSinceDate:begin]);

由子线程回归到主线程:

在子线程的方法里调:

[self performSelectorOnMainThread:@selector(loadImage:) withObject:image waitUntilDone:YES];

[self performSelector:@selector(loadImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
[self.imageView performSelector:@selector(setImage:)onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];

说明:waitUntilDone:YES,等@selector里的方法执行完后,才执行之后的代码,

waitUntilDone:NO, @selector里的方法和之后的代码是并发执行的。
在这里插入图片描述

转载地址:http://bpwin.baihongyu.com/

你可能感兴趣的文章
2.2处理机调度
查看>>
2.3进程同步
查看>>
2.3浮点数的表示与运算
查看>>
2.4死锁
查看>>
2.4算术逻辑单元(ALU)
查看>>
3.1.1内存管理概念
查看>>
矩阵论——向量空间
查看>>
吴恩达机器学习——数值评价指标
查看>>
矩阵论——正交矩阵&Gram-Schimidt正交化
查看>>
Python语法——实现nc文件可视化的基本模块
查看>>
Anaconda完全入门指南
查看>>
如何创建、添加虚拟环境
查看>>
Anaconda prompt和cmd的区别
查看>>
第一个nc文件的信息读取
查看>>
netCDF——nc文件读取
查看>>
使用BaseMap绘制地图它不香么
查看>>
MeteoInfo介绍
查看>>
Basemap系列教程:使用shapefiles绘制地图
查看>>
numpy生成掩码数组
查看>>
np.squeeze():把张量中维度为1的维度去掉
查看>>