情景再现:在项目中遇到从数据库加载大量数据的情况,为了避免卡顿的现象,所以另开一个线程进行数据库读写操作,然后用广播通知主线程刷新。但是实际运行起来,界面并没有更新。
难道数据没读出来,单步调试一下,排除了这种可能。再想想其他原因,主界面不刷新,大部分情况下都是因为代码没有在主线程进行,打上断点结果如下,发现果然不在主线程:
顺藤摸瓜,发现Notification并没有在主线程内发出,利用GCD在主线程里发送广播,问题解决。
原因:这里借助苹果官方文档里的描述
(https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Notifications/Articles/NotificationQueues.html#//apple_ref/doc/uid/20000217-SW1)
In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.大概意思是在哪个线程内发广播,那么接受广播后的代码就在这个线程执行。
优化:那么如果代码中存在很多这种发送广播刷新UI的时候,岂不是每次发的时候都要判断一下是不是在主线程,比较麻烦。所以给刷新UI的代码加上GCD主线程执行,也能达到同样的效果。
延伸:Notification是iOS中常用的通信方式,那么其他方式如KVO、delegate一样也会存在这种问题,所以在异步加载数据刷新界面的时候都需要在主线程进行。