iOS开发- reloadData无效 (子线程更新UI错误)

今天在写一个聊天工具的时候遇到了一个问题。

注册的通知里面, 每当有其他用户发来消息的时候,  UITableView 就要重新更新

[objc] view plaincopy

  1. cell.textLabel.textColor = [UIColor redColor];

使用红色标记cell名字来突出显示新消息。  (当然,, 这只是个demo, 效果比较渣。  正常情况应该是用户头像跳动或者显示新消息条数...)

可是我发现,  调用了这样的更新语句后, UITableVIew里面的数据并没有刷新。

[objc] view plaincopy

  1. - (void)sessionUpdated:(NSNotification *)notification
  2. {
  3. [myTableView reloadData];
  4. }

设了下断点, 发现没有回调其Delegate的numberOfRowsInSection和CellForRow,所以导致界面没有更新。

这就费解了。

然后我手动的拖拽UI Tableview, 使其重绘, 发现数据更新了。 正常显示, 变红。

说明逻辑是没错的。 只是调用了reloadData后每效果。

之后就是百度学习了。

总结如下:

结论:

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

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

故而, 更新UI要在主线程中执行, 把上述代码改成这样

[objc] view plaincopy

    1. - (void)sessionUpdated:(NSNotification *)notification
    2. {
    3. dispatch_async(dispatch_get_main_queue(), ^{
    4. [myTableView reloadData];
    5. });
时间: 2024-10-05 12:37:42

iOS开发- reloadData无效 (子线程更新UI错误)的相关文章

Android开发——实现子线程更新UI

Android中线程按功能分的话,可以分为两个,一个是主线程(UI线程),其他的都是子线程 主线程不能执行那些耗时过长的代码或任务(执行耗时过长的代码会出现应用未响应的提示),所以都是使用子线程来执行耗时过长的代码,比如说下载文件等任务 一般情况,子线程中执行过长的代码,都是需要进行更新UI操作. 但是Android中,为了防止安全,是不允许在子线程更新UI的,但是我们可以使用到Android官方给予的API来实现子线程更新UI的操作(本质上,这些API也是切换回了主线程来进行更新UI) 例子:

Android子线程更新UI主线程方法之Handler

背景: 我们开发应用程序的时候,处于线程安全的原因子线程通常是不能直接更新主线程(UI线程)中的UI元素的,那么在Android开发中有几种方法解决这个问题,其中方法之一就是利用Handler处理的. 下面说下有关Handler相关的知识. 多线程一些基础知识回顾:在介绍Handler类相关知识之前,我们先看看在Java中是如何创建多线程的方法有两种:通过继承Thread类,重写Run方法来实现通过继承接口Runnable实现多线程 具体两者的区别与实现,看看这篇文章中的介绍:http://de

WPF Dispatcher.BeginInvoke子线程更新UI

原文:WPF Dispatcher.BeginInvoke子线程更新UI 在开发WPF应用时出现:"调用线程无法访问此对象,因为另一个线程拥有该对象." 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者Invoke()方法. Dispatcher.BeginInvoke() //异步执行,不等待委托结束就更新 Dispatcher.Invoke()          //代表同步执行 Action()       

子线程更新UI界面的2种方法

一.一般我们都会在子线程完成一些耗时的操作. 1.Android中消息机制: 2.知识点: Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理.                      Handler:处理者,负责Message的发送及处理.使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等.                    

Qt 子线程更新Ui

最近做练习,写一个Qt版的飞机大战,需要用子线程更新UI,发现Qt子线程不能更新Ui,否则程序会崩溃.在网上百度了下,说是需要在子线程自定义信号,然后在线程回调的run()函数里发射信号,主线程连接信号和槽,然后在槽函数里面更新UI.虽然最后发现这个办法对我写飞机大战没有啥帮助,但是感觉这个办法还是需要总结下来的.(最后我是用的定时器更新的UI界面) 废话不多说,下面是子线程更新UI的方法: 第一步:写一个线程类,继承自QThread 第二步:自定义信号 class CMyThread : pu

Python+PyQT5的子线程更新UI界面的实例《新手必学》

今天小编就为大家分享一篇Python+PyQT5的子线程更新UI界面的实例,具有很好的参考价值,希望对大家有所帮助.一起跟随小编过来看看吧子线程里是不能更新UI界面的,在移动端方面.Android的UI访问是没有加锁的,多个线程可以同时访问更新操作同一个UI控件.也就是说访问UI的时候,android系统当中的控件都不是线程安全的,这将导致在多线程模式下,当多个线程共同访问更新操作同一个UI控件时容易发生不可控的错误.所以Android中规定只能在UI线程中访问UI,相当于从另一个角度给Andr

C#子线程更新UI控件的方法总结

http://blog.csdn.net/jqncc/article/details/16342121 在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从子线程直接修改控件属性时会出现“从不是创建控件的线程访问它”的异常提示. 跨线程更新UI控件的常用方法有两种: 1.使用控件自身的invoke/BeginInvoke方法 2.使用SynchronizationContext的Post/Send方法更新 1.使用控件自身的invoke/BeginIn

Android 子线程 更新 UI 界面 总结

package com.jrhcode.morethreadtest; import java.util.concurrent.Executors; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.view.Menu; import android.widget.TextView; import

Android 子线程更新UI 异常

众所周知,Android是不可以在子线程中直接更新UI的,需要借助Handler或者View.post(Runnable runnable)或者runOnUIThread(Runnable runnable)将更新的代码切入到主线程中去实现UI更新. 我们来试一下,在Activity的 onCreate中直接在新线程中去更新一个TextView的文本,结果发现,WHAT?竟然没有抛出异常,更新也成功了? 这是因为在onCreate中尚未完成View的绘制,此时TextView中有个变量mLayo