iOS ------ 多线程 pthread,NSThread

一,pthread

1.1pthread简介

pthread是一套通用的多线程的API,可以在Unix/Linux/Windows等系统跨平台使用,使用C语言编写,需要程序员自己管理线程的生命周期,使用难度大。

1.2pthread使用方法

1,首先要包含头文件#import<pthread.h>
2,其次要创建线程,并开启线程任务

- (void)viewDidLoad {[super viewDidLoad];//创建线程,定义一个pthread类型变量,为指向线程的指针pthread_t thread;//定义一个OC对象用于传递参数NSObject* obj = [[NSObject alloc] init];NSLog(@"objc:%p", obj);//开启线程:执行任务int result  = pthread_create(&thread, NULL, run, (__bridge void*)(obj));if (result == 0) {NSLog(@"创建线程成功");} else {NSLog(@"创建线程失败");}//设置子线程的状态为detached,该线程结束自动释放所有资源pthread_detach(thread);NSLog(@"%@", [NSThread currentThread]);// Do any additional setup after loading the view.
}
void * run(void* param) {NSLog(@"%@ param: %p", [NSThread currentThread], param);NSObject* instance = (__bridge NSObject*)parm;[instance 调用方法]return NULL;
}

上面将OC对象包装在符合签名的C函数中。
在创建线程时,我们将OC对象桥接为 void * 类型传递给 pthread_create。使用“桥接”(bridge)来处理指针类型转换是因为OC与C语言在内存管理和类型系统上存在差异。如果不使用桥接,ARC 可能认为对象不再需要管理,导致对象在转换后可能被释放。使用 __bridge 明确告诉 ARC 不要改变引用计数。

在函数中使用使用参数对象,调用他的方法。也需要使用桥接。如果没用使用桥接ARC 可能认为这是一个新的对象,需要增加引用计数。使用 __bridge 明确告诉 ARC 这是一个已有对象,不要改变引用计数。

pthread_create 是一个标准的 C 语言函数,用于创建一个新线程。它的函数签名如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
  • 第一个参数 pthread_t *thread:指向线程标识符的指针。
  • 第二个参数 const pthread_attr_t *attr:指向线程属性对象的指针。如果为 NULL,则使用默认属性。
  • 第三个参数 void *(*start_routine) (void *):线程启动函数的指针。
  • 第四个参数 void *arg:传递给线程启动函数的参数。

1.3 pthread 其他相关方法

  • pthread_create() 创建一个线程
  • pthread_exit() 终止当前线程
  • pthread_cancel() 中断另外一个线程的运行
  • pthread_join() 阻塞当前的线程,直到另外一个线程运行结束
  • pthread_attr_init() 初始化线程的属性
  • pthread_attr_setdetachstate() 设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
  • pthread_attr_getdetachstate() 获取脱离状态的属性
  • pthread_attr_destroy() 删除线程的属性
  • pthread_kill() 向线程发送一个信号

二,NSThead

NSThread 是苹果官方提供的,使用起来比 pthread 更加面向对象,简单易用,可以直接操作线程对象。不过也需要需要程序员自己管理线程的生命周期(主要是创建),我们在开发的过程中偶尔使用 NSThread。比如我们会经常调用[NSThread currentThread]来显示当前的进程信息.

2.1,创建,启动线程

  • 先创建线程,在启动线程
// 1. 创建线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
// 2. 启动线程
[thread start];    // 线程一启动,就会在线程thread中执行self的run方法// 新线程调用方法,里边为需要执行的任务
- (void)run {NSLog(@"%@", [NSThread currentThread]);
}
  • 创建线程后自动启动线程
// 1. 创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];// 新线程调用方法,里边为需要执行的任务
- (void)run {NSLog(@"%@", [NSThread currentThread]);
}
  • 隐式创建并启动线程
    这段代码用于在后台线程中异步执行实例方法 run。这种方法常用于执行需要较长时间完成的任务,而不阻塞主线程的操作
// 1. 隐式创建并启动线程
[self performSelectorInBackground:@selector(run) withObject:nil];// 新线程调用方法,里边为需要执行的任务
- (void)run {NSLog(@"%@", [NSThread currentThread]);
}

2.2,线程相关方法

// 获得主线程
+ (NSThread *)mainThread;    // 判断是否为主线程(对象方法)
- (BOOL)isMainThread;// 判断是否为主线程(类方法)
+ (BOOL)isMainThread;    // 获得当前线程
NSThread *current = [NSThread currentThread];// 线程的名字——setter方法
- (void)setName:(NSString *)n;    // 线程的名字——getter方法
- (NSString *)name;    

2.3线程状态控制方法

  • 启动线程方法
- (void)start;
// 线程进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
  • 阻塞(停止)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 线程进入阻塞状态
  • 强制停止线程
+ (void)exit;
// 线程进入死亡状态

2.4,线程之间的通信
在开发中,我们通常会在子线程进行耗时操作,操作结束后在回到主线程去刷新UI,这就涉及到子线程和主线程之间的通信。官方关于 NSThread 的线程间通信的方法。

// 在主线程上执行操作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray<NSString *> *)array;// equivalent to the first method with kCFRunLoopCommonModes// 在指定线程上执行操作
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);// 在当前线程上执行操作,调用 NSObject 的 performSelector:相关方法
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

一个下载图片的例子,先开启一个子线程,在子线程中下载图片。再回到主线程刷新 UI,将图片展示在 UIImageView 中。

- (void)viewDidLoad {[super viewDidLoad];self.imageView = [[UIImageView alloc] init];self.imageView.frame = CGRectMake(100, 100, 100, 100);[self.view addSubview:self.imageView];[self downloadImageOnSubThread];
}
- (void)downloadImageOnSubThread {//在创建的子线程调用downloadImage下载图片[NSThread detachNewThreadSelector:@selector(downloadImage) toTarget:self withObject:nil];
}
- (void)downloadImage {NSLog(@"current thread -- %@", [NSThread currentThread]);NSURL* imageUrl = [NSURL URLWithString:@"https://ysc-demo-1254961422.file.myqcloud.com/YSC-phread-NSThread-demo-icon.jpg"];//从imageURL中读取图片(下载图片)耗时操作NSData* imageData = [NSData dataWithContentsOfURL:imageUrl];//痛过二进制data创建imageUIImage* image = [UIImage imageWithData:imageData];//回到主线程进行图片的赋值和页面的刷新[self performSelectorOnMainThread:@selector(refreshOnMainThread:) withObject:image waitUntilDone:YES];
}
- (void)refreshOnMainThread:(UIImage*) image {NSLog(@"current thread -- %@", [NSThread currentThread]);//将图片复制到imageView上self.imageView.image = image;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

奶奶也能看懂的耦合协调度分析

不会计算&#xff1f;跟着文献学起来~ 案例数据连接&#xff08;复制链接后粘贴到浏览器中&#xff09;&#xff1a; 耦合协调度数据​spssau.com/spssaudata.html?shareDataF363000CD033FF15E557BB75B9B0D412 假如你有这样一组数据&#xff1a; 如何进行计算分析耦合协调度…

【mmdet问题】error: unrecognized arguments: --local-rank=0

Note that --use-env is set by default in torchrun. If your script expects --local-rank argument to be set, please change it to read from os.environ[LOCAL_RANK] instead. See https://pytorch.org/docs/stable/distributed.html#launch-utility for 如果直接使用gi…

内网安全之证书模版的管理

证书模板 Certificate templates 是 CA 证书颁发机构的一个组成部分&#xff0c;是证书策略中的重要元素&#xff0c;是用于证书注册、使用和管理的一组规则和格式。当 CA 收到对证书的请求时&#xff0c;必须对该请求应用一组规则和设置&#xff0c;以执行所请求的功能&#x…

前端知识1-4:性能优化进阶

性能优化进阶 Navigation Timing API navigationStart / end 表示从上一个文档卸载结束时 > 如果没有上一个文档&#xff0c;这个值和fetchStart相等 unloadEventStart / end 标识前一个网页unload的时间点 redirectStart / end 第一个http重定向发生和结束的时间 fetch…

CSP垦田计划

第一次的代码&#xff0c;直接暴力&#xff0c;因为结果的上限就是最大值&#xff0c;下限是k&#xff0c;直接从最大值遍历到k找到答案&#xff1a; #include<bits/stdc.h> using namespace std; const int N 1e510; const int mod 1e97; typedef long long ll; int …

Hadoop3:HDFS中DataNode与NameNode的工作流程

一、DataNode中的数据情况 数据位置 /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-823420375-192.168.31.102-1714395693863/current/finalized/subdir0/subdir0块信息 每个块信息&#xff0c;由两个文件保存&#xff0c;xxx.meta保存的是数据长度、校验和、时间戳&am…

芝加哥大学最新研究:GPT-4与财务预测,重塑财务分析的未来

最近&#xff0c;芝加哥大学的研究团队发表了一篇突破性的研究&#xff0c;展示了大型语言模型&#xff08;LLM&#xff09;&#xff0c;特别是 OpenAI 开发的 GPT-4&#xff0c;如何在财务报表分析领域取得了与专业分析师相匹配甚至超越的表现。这项研究不仅凸显了人工智能在高…

nginx负载均衡配置详解

Nginx 的负载均衡功能是通过 upstream 模块来实现的&#xff0c;允许将客户端的请求分发到多个后端服务器&#xff0c;以达到分散负载、提高系统稳定性和响应速度的目的。下面是一些关于 Nginx 负载均衡配置的详细说明&#xff1a; 1. 定义 Upstream Block 首先&#xff0c;在…

创新驱动!IvorySQL 与 Neon 适配,打造兼容Oracle的垂直扩展解决方案

IvorySQL近期宣布已成功完成与 Neon 垂直自动扩展适配&#xff0c;标志着 IvorySQL开源数据库在云环境资源自动管理领域取得重要提升。这次适配不仅验证了 IvorySQL 的功能和灵活性&#xff0c;还展示了其在应对复杂数据库资源管理的适应能力。 对于企业用户而言&#xff0c;意…

GDPU Java 天码行空13

&#xff08;一&#xff09;实验目的 1、掌握JAVA中与网络程序开发相关的知识点&#xff1b; 2、理解并掌握网络编程开发思想及方法&#xff1b; 3、熟悉项目开发的分包方法和依据&#xff1b; 4、实现聊天室中客服端和服务器端的实现方法&#xff1b; 5、熟悉多线程程序开发方…

Kinetix5700罗克韦尔AB伺服驱动器维修2198-D020-ERS3

Allen-Bradley罗克韦尔运动控制/伺服驱动器维修Kinetix 5700/Kinetix 6000/Kinetix 5500等系列电机驱动器/运动控制系统维修。 AB驱动器的控制接口有两种类型&#xff1a; 类型1&#xff1a;脉冲接口 类型2&#xff1a;模拟量接口 大部分小型PLC和伺服驱动器的链接方式都是开…

通过vlan实现同一网段下的网络隔离

现有两个电脑通过交换机直接连接在一起 pc1&#xff1a; pc2&#xff1a; 正常状态下是可以ping成功的 现在先进入交换机命令行界面&#xff0c;创建两个vlan <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]vlan 10 [Huawei-vlan10…

归纳跨域几种解决方案

什么是跨域&#xff1f; **说起跨域&#xff0c;就要知道什么是浏览器同源策略 **浏览器同源策略&#xff1a;必须是协议、域名、端口完全一致的才符合同源策略 **如果以上三项&#xff0c;有一项不同都涉及到跨域问题 为什么浏览器要设置同源策略呢&#xff1f; 没有同源策…

2024年西安交通大学程序设计校赛

A题 签到题 代码如下 //A #include<iostream> #include<algorithm> #define int long long #define endl \n #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); using namespace std; signed main() {IOSint a,b,c,d;cin>>a>>b>>c…

二叉树介绍及堆

文章目录 树 概念及结构 二叉树 概念及结构 特殊的二叉树 完全二叉树 满二叉树 性质 储存 顺序存储 链式储存 堆 概念及结构 小堆 大堆 建堆 向上调整建堆 向下调整建堆 TOPK问题 法一&#xff1a; 法二&#xff1a; 树 概念及结构 树是一种非线性的数据…

解决word里加入mathtype公式后行间距变大

1.布局>页面设置>文档网格&#xff0c;网格栏选为无网格 2.固定间距

探索标准差与方差的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、标准差与方差的基础理解 代码案例 二、标准差与方差的计算方法 方差的计算 标准差的…

QT——QSlider实现,QT滑动控件的使用

目录 简介滑动块调节两种方法滑动条触发信号量理想滑动块运用&#xff08;参考&#xff09; 简介 QT中滑动条的控件叫QSlider&#xff0c;继承自QAbstractSlider类。 主要用途是通过滑块的滑动的方式在一定范围内调节某个值。根据调节的后得到的结果去执行一些处理&#xff0c…

【AI基础】数据获取与整理、打标、增强方法、增强库imgaug

文章目录 常见的数据集网站爬虫工具使用搜索引起图片爬虫视频网站爬虫 数据整理数据检查和清洗数据去重数据集划分 数据标注数据标注工具 label studio 数据增强什么是数据增强单样本数据增强多样本数据增强样本生成方法数据增强imgaugimgaug 操作imgaug 使用 常见的数据集网站…

这款AI绘画软件,带你快速生成高质量产品效果图!

前言 随着人工智能技术的飞速发展&#xff0c;AI在设计领域的应用越来越广泛&#xff0c;。今天&#xff0c;介绍的一款能够自动生成高质量产品效果图的AI绘画软件——STARTAI。这款软件以其强大的功能和便捷的操作&#xff0c;正在重新定义电商产品效果图的制作流程。 AI局部…