美文网首页iOS OCiOS日常须知
iOS 开发中为什么更新UI都要放在主线程中?

iOS 开发中为什么更新UI都要放在主线程中?

作者: 莫许 | 来源:发表于2016-06-22 23:39 被阅读1245次

    原因有2个:

    1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新

    2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

    1、程序一开始运行就进入了主线程

    2、处理某些数据太过费时,影响用户交互,可以开辟子线程处理,然后通知主线程进行界面更新

    测试代码:

    开辟一个多线程,直接在子线程里进行ui 更新:

    -(void)testUIRefresh:(UIButton *)button{

    [NSThread detachNewThreadSelector:@selector(beginTest) toTarget:self withObject:nil];

    }

    -(void)beginTest{

    NSLog(@” 当前线程%@”,[NSThreadcurrentThread]);

    NSLog(@” 主线程%@”,[NSThreadmainThread]);

    //该button 为响应 testUIRefresh的button

    [self.button setTitle:@"AAA" forState:0];

    }

    2012-11-15 12:14:02.147 TestProj[2455:1b07]当前线程{name = (null), num = 3}

    2012-11-15 12:14:02.147 TestProj[2455:1b07]主线程{name = (null), num = 1}

    结果:当前的确是在子线程中,但是UI马上更新了??

    结果分析:大家都说UI更新在主线程中做,上面的结果怎么解释

    假设:如果在子线程里做了UI更新,待子线程运行完毕,程序自动进入 主线程进行指定的ui更新!

    问题:如果子线程没结束呢?

    在分线程中加入:

    -(void)beginTest{

    NSLog(@” 当前线程%@”,[NSThreadcurrentThread]);

    NSLog(@” 主线程%@”,[NSThreadmainThread]);

    //该button 为响应 testUIRefresh的button

    [self.button setTitle:@"AAA" forState:0];

    [NSThread sleepForTimeInterval:4.0];

    }

    结果:

    self.button的title还是马上更新了

    结果分析:难道上面的假设不成立?

    问题:这次在分线程中add 一个button

    -(void)beginTest{

    NSLog(@” 当前线程%@”,[NSThreadcurrentThread]);

    NSLog(@” 主线程%@”,[NSThreadmainThread]);

    //该button 为响应 testUIRefresh的button

    [self.button setTitle:@"AAA" forState:0];

    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];

    [backButton setTitle:@"测试runloop" forState:0];

    [backButton setTitleColor:[UIColor redColor] forState:0];

    backButton.frame = CGRectMake(100, 200, 100, 50);

    [backButton addTarget:self action:@selector(testRunLoop)forControlEvents:UIControlEventTouchUpInside];

    [self.window addSubview:backButton];

    [NSThread sleepForTimeInterval:4.0];

    }

    结果:[self.button setTitle:@"AAA" forState:0];马上响应了,但是添加的这个Button却一直等到线程结束才绘制出来

    分析:在子线程中:如果要对其他UI 进行更新,则必须等到该子线程运行结束,而对响应用户点击的Button的UI更新则是及时的!不管他是在主线程还是在子线程中做的更新,意义都不大了,因为子线程中对所有其他ui更新都要等到该子线程生命周期结束才进行。

    结论:

    1、在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新

    2、只有极少数的UI能,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义

    相关文章

      网友评论

      • 境雅随安:如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新 这句话有语法错误吧 ,都读不通。你是想表达的是 “主线程无法获知,子线程中的UI更新的内容”吧

      本文标题:iOS 开发中为什么更新UI都要放在主线程中?

      本文链接:https://www.haomeiwen.com/subject/asundttx.html