当前位置: 首页 > news >正文

iOS 回到主线程刷新UI

在iOS 里面,项目打开就会运行一个主线程,所有的UI都在主线程里进行.其他网络请求或者耗时操作理论上也可以在主线程运行,但是如果太耗时,那么就会影响主线程其他UI.所以需要开字线程来进行耗时操作,子线程进行完耗时操作之后,如果项目需求有需要刷新UI,或者改变UI,一定得回到主线程进行修改/刷新.

下面介绍三种iOS里线程模式

前情提要:在View上创建一个UILabel, 点击屏幕空白处开启一个子线程,在子线程里模拟耗时操作,耗时操作完毕后需要改变UILabel上的文字.

- (void)viewDidLoad 
{[super viewDidLoad];self.markLabel = [[UILabel alloc]initWithFrame:CGRectMake(50, 200, 300, 40)];self.markLabel.backgroundColor = [UIColor greenColor];self.markLabel.textAlignment = NSTextAlignmentCenter;self.markLabel.text = @"子线程开启之前的String";[self.view addSubview:self.markLabel];
}

1.NSThread

1.1. 点击空白页面,开启线程(先模拟不在主线程刷新UI的错误写法)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//模拟线程耗时操作,并在耗时操作后改变label的String[self threadModel];
}- (void)threadModel
{NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadUpdateUI) object:nil];[thread start];
}- (void)threadUpdateUI
{//模拟耗时操作[NSThread sleepForTimeInterval:2];//耗时操作后直接刷新UI (这是模拟错误的方法)self.markLabel.text = @"修改后的Sting"; 
}

按照以上的写法,直接报错,报错提示如下图所示: 

must be used from main thread only : 一定且只有从主线程刷新

因此可知,需要进入主线程去刷新,那么NSTread模式怎么进入主线程呢? 看下面的代码

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//模拟线程耗时操作,并在耗时操作后改变label的String[self threadModel];
}- (void)threadModel
{NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadUpdateUI) object:nil];[thread start];
}- (void)threadUpdateUI
{//模拟耗时操作[NSThread sleepForTimeInterval:2];//NSThread 找到主线程[self performSelectorOnMainThread:@selector(uodateMainUI) withObject:nil waitUntilDone:NO];}- (void)uodateMainUI
{self.markLabel.text = @"修改后的Sting";
}

以上是NSThread 找到主线程,并且刷新UI的方法.

接下来介绍CGD和NSOperation 找到主线程的方法

2.CGD

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//模拟线程耗时操作,并在耗时操作后改变label的String[self CGDModel];
}- (void)CGDModel
{//队列dispatch_queue_t queue = dispatch_get_global_queue(0, 0);/*我这里使用global_queue来模拟,你也可以使用并发队列/串行队列模拟dispatch_queue_t queue = dispatch_queue_create(@"并发队列", DISPATCH_QUEUE_CONCURRENT);dispatch_queue_t queue = dispatch_queue_create(@"串行队列", DISPATCH_QUEUE_SERIAL);但是不能用主队列来模拟,因为主队列本身就有主线程*///任务dispatch_async(queue, ^{//模拟耗时操作[NSThread sleepForTimeInterval:2];//CGD模式回到主线程,因为CGD和NSOperation只有任务和队列的概念,所以主队列就是主线程dispatch_async(dispatch_get_main_queue(), ^{self.markLabel.text = @"修改后的Sting";});});
}

3.NSOperation

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{//模拟线程耗时操作,并在耗时操作后改变label的String[self operationModel];
}- (void)operationModel
{//队列NSOperationQueue * queue = [[NSOperationQueue alloc]init];//任务[queue addOperationWithBlock:^{//模拟耗时操作[NSThread sleepForTimeInterval:2];//找到主队列(NSOperation只有任务和队列的概念,所以主队列就是主线程)[NSOperationQueue.mainQueue addOperationWithBlock:^{self.markLabel.text = @"修改后的Sting";}];}];
}

http://www.lryc.cn/news/466036.html

相关文章:

  • Spring Data 技术详解与最佳实践
  • ubuntu下安装图片编辑工具shutter
  • 代码随想录算法训练营Day38 | 62. 不同路径、63. 不同路径 II
  • TrickMo 安卓银行木马新变种利用虚假锁屏窃取密码
  • Java | Leetcode Java题解之第493题翻转对
  • uniapp scroll-view翻转90度后,无法滚动问题,并设置滚动条到最底部(手写横屏样式)
  • 腾讯PAG 动画库Android版本的一个问题与排查记录
  • 计算机的算术运算之浮点数
  • Sqlite3 操作笔记
  • mysqlRouter读写分离
  • 【修订中】ffmpeg 知识点
  • Rust初踩坑
  • element-ui 的el-calendar日历组件样式修改
  • LinuxDebian系统安装nginx
  • Redis 数据类型Streams
  • 基智科技CEO张文战:探索火山引擎数据飞轮模式下的大模型应用新机会
  • 【AUTOSAR标准文档】AotuSar结构横向分层详解(RTE、BSW)
  • 新 Chrome 插件可检测 AI 伪造声音;Canary Speech 推出用于临床对话的语音分析技术丨 RTE 开发者日报
  • 1. 路由定义
  • 我们可以用微服务创建状态机吗?
  • 邦芒贴士:职场新人需远离的7种坏习惯
  • 面向医院的统一支付平台产品经验分享
  • http作业
  • AlDente Pro for Mac电脑 充电限制保护工具 安装教程【简单,轻松上手】
  • C语言数据结构之算法复杂度
  • HDU RSA
  • 数据仓库建设 : 主题域简介
  • 开源表单生成器OpnForm
  • Zookeeper面试整理-Zookeeper的基础概念
  • 验证archive_command配置是否正确