zoukankan      html  css  js  c++  java
  • 关于iOS刷新UI需要在主线程执行

    为什么一定要在主线程刷新UI?
    安全+效率:因为UIKit框架不是线程安全的框架,当在多个线程进行UI操作,有可能出现资源抢夺,导致问题。

    其实:在子线程是不能更新UI的, 看到能更新的结果只是个假象。因为:在子线程代码完成之后,回到主线程,然后执行了子线程的更新UI的代码,由于这个时间很短,所以看起来是能够在子线程刷新UI的。想验证的话也很简单,看下面demo:点击按钮,会开启一个子线程,然后在子线程中刷新该按钮的标题,再新建一个按钮,最后一行代码是延迟5秒。

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self.view addSubview:self.button];   
    }
    
    -(UIButton *)button{
        if (!_button) {
            _button = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, SCREEN_WIDTH, 100)];
            _button.backgroundColor = [UIColor yellowColor];
            [_button addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
            [_button setTitle:@"UI" forState:UIControlStateNormal];
            [_button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
            _button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
            _button.titleLabel.font = [UIFont systemFontOfSize:13];
        }
        return _button;
    }
    
    - (void)btnClicked {
        [NSThread detachNewThreadSelector:@selector(uiRefreashTest) toTarget:self withObject:nil];
    }
    
    - (void)uiRefreashTest {
        NSLog(@"当前线程:%@", [NSThread currentThread]);
        NSLog(@"主线程:%@", [NSThread mainThread]);
        
        //在子线程刷新该按钮的标题名字为子线程信息
        NSString *subStr = [NSString stringWithFormat:@"子线程:%@", [NSThread currentThread]];
        NSString *mainStr = [NSString stringWithFormat:@"主线程:%@", [NSThread mainThread]];
        [_button setTitle:subStr forState:UIControlStateNormal];
        CGRect labelTitleSize = [subStr boundingRectWithSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13]} context:nil];
        _button.frame = CGRectMake(0, 100, labelTitleSize.size.width+10, labelTitleSize.size.height+10);
        
        //在子线程新建一个按钮,标题名字为主线程信息
        UIButton *newBtn = [[UIButton alloc] init];
        newBtn.backgroundColor = [UIColor greenColor];
        newBtn.titleLabel.font = [UIFont systemFontOfSize:13];
        newBtn.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
        [newBtn setTitle:mainStr forState:UIControlStateNormal];
        [newBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        CGRect labelTitleSize01 = [mainStr boundingRectWithSize:CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13]} context:nil];
        
        newBtn.frame = CGRectMake(0, 250, labelTitleSize01.size.width+10, labelTitleSize01.size.height+10);
        [self.view addSubview:newBtn];
        
        //在这个子线程延迟5秒钟
        sleep(5);
    }
    

      

    执行结果:

     
    333.gif

    结果分析:
    从图中点击按钮后,虽然任务是在同一个子线程执行,但是并没有按顺序执行,而是首先立即执行NSLog日志输出,但是接下来并没有执行刷新按钮标题,和新建按钮的代码,而是优先执行sleep(5)延迟代码,然后才执行的刷新和新建控件的代码

    。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    转自简书
    作者:wg刚
    链接:https://www.jianshu.com/p/8d0aa880d55b
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    iPhone电话与短信相关代码小结
    时间都去哪儿了?开源一个统计iPhone上App运行时间和打开次数的小工具【iOS8已失效】
    分享一个仿网易新闻客户端iPhone版的标签式导航ViewController
    iOS推送小结(证书的生成、客户端的开发、服务端的开发)
    Argy1risMatrix1
    2019河南模考题
    撮箕2020-3-8
    数学符号md
    2014全国甲&2015福建-几何题
    零点
  • 原文地址:https://www.cnblogs.com/8335IT/p/10373723.html
Copyright © 2011-2022 走看看