首页 > 其他分享 >iOS 回到主线程刷新UI

iOS 回到主线程刷新UI

时间:2024-10-22 21:47:49浏览次数:9  
标签:NSThread self iOS queue 耗时 UI 刷新 线程 void

在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";
        }];
    
    }];
}

标签:NSThread,self,iOS,queue,耗时,UI,刷新,线程,void
From: https://blog.csdn.net/wyz670083956/article/details/143107910

相关文章

  • 前后端实现双Token无感刷新用户认证
    前后端实现双Token无感刷新用户认证本文记录了使用双Token机制实现用户认证的具体步骤,前端使用的Vue,后端使用SpringSecurity和JWT双Token分别指的是AccessToken和RefreshTokenAccessToken:每次请求需要携带AccessToken访问后端数据,有效期短,减少AccessToken泄露带来的风险Refres......
  • ArkUI-Image详解
    ArkUI-Image详解本地资源创建文件夹,将本地图片放入ets文件夹下的任意位置。Image组件引入本地图片路径,即可显示图片(根目录为ets文件夹)。Image('images/pic1.webp').width(100).height(100)Resource资源使用资源格式可以跨包/跨模块引入图片,resources文件......
  • iOS - Swift 正则校验场景总结
    1.校验是否只含有“数字和字母”或者“字母”classfunccheckUserName(_username:String)->Bool{    letregex=try?NSRegularExpression(pattern:"^(?![0-9]+$)[0-9A-Za-z]{8,16}$",options:[])    returnregex?.firstMatch(in:usernam......
  • HarmonyOS ArkUI性能优化实践:长列表加载性能优化
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(MaoistLearning)➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/p/......
  • 缺少exuikrn.dll文件怎么解决?exuikrn.dll找不到的处理方法
    exuikrn.dll是一个动态链接库文件,它可能与某些特定的应用程序或系统组件相关联。当您的计算机上缺少这个文件时,可能会遇到应用程序无法正常启动、运行时错误或者系统不稳定等问题。本指南将提供几种解决此问题的方法。解决方案一:重新安装相关软件1.识别缺失原因:首先确定是......
  • 移动开发(四):.NET MAUI中Android应用修改安装图标和启动页面
    今天继续给大家分享.NETMAUI中开发的Android应用如何修改安装图标和启动页面,希望对大家使用Net开发安卓APP提供一些帮助!一、更换APP应用图标这里我们直接编辑项目文件MyFirstMauiApp.csproj来修改APP应用图标官方案例默认的组合图标,其中ForegroundFile表示前景图像(选填),Inclu......
  • element-ui中,使用this.$message.success(“登录成功“),如何修改文字的样式呢?
    在element-ui中使用this.$message.success(“注册成功”);时,直接修改文字样式并没有暴露出很方便的接口,因为ElementUI的消息提示组件Message是通过JavaScript动态创建的。但是你可以通过以下方法自定义消息的样式:方法1:使用customClass属性ElementUI的Me......
  • 在iOS开发中如何使用Core Data管理数据持久化
    摘要:在iOS开发中运用CoreData管理数据持久化包括以下要点:1、掌握CoreData框架基础;2、实现数据模型的设计;3、熟悉数据存储与检索;4、利用上下文管理数据;5、数据迁移和版本控制。在这其中,数据模型的设计是核心,它影响整个应用的数据结构和未来的扩展性。数据模型设计指的是在Xcode中......
  • MAUI程序如何部署到MIUI手机上?
    由于VS2022的安卓仿真器启动速度奇慢且进入仿真系统后鼠标操作非常卡时常出现界面无响应的提示因此,要考虑直接部署到安卓手机上本人手机的MIUI版本号是13.0.7稳定版1.设置->我的设备->全部参数->MIUI版本>连续点击“MIUI版本”7次,直到看到“您已处于开发者模式”提示框闪现......
  • 使用Radzen Blazor组件库开发的基于ABP框架炫酷UI主题
    一、项目简介使用过ABP框架的童鞋应该知道它也自带了一款免费的BlazorUI主题,它的页面是长这样的:个人感觉不太美观,于是网上搜了很多Blazor开源组件库,发现有一款样式非常不错的组件库,名叫:Radzen,它的组件库案例网址是:SampleBlazorDashboard|FreeUIComponentsbyRadzen,比较......