情景再現(xiàn):在項(xiàng)目中遇到從數(shù)據(jù)庫(kù)加載大量數(shù)據(jù)的情況,為了避免卡頓的現(xiàn)象着逐,所以另開(kāi)一個(gè)線程進(jìn)行數(shù)據(jù)庫(kù)讀寫(xiě)操作呕童,然后用廣播通知主線程刷新漆际。但是實(shí)際運(yùn)行起來(lái),界面并沒(méi)有更新夺饲。
難道數(shù)據(jù)沒(méi)讀出來(lái)奸汇,單步調(diào)試一下施符,排除了這種可能。再想想其他原因擂找,主界面不刷新戳吝,大部分情況下都是因?yàn)榇a沒(méi)有在主線程進(jìn)行,打上斷點(diǎn)結(jié)果如下婴洼,發(fā)現(xiàn)果然不在主線程:
順藤摸瓜骨坑,發(fā)現(xiàn)Notification并沒(méi)有在主線程內(nèi)發(fā)出,利用GCD在主線程里發(fā)送廣播柬采,問(wèn)題解決欢唾。
原因:這里借助蘋(píng)果官方文檔里的描述
(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.大概意思是在哪個(gè)線程內(nèi)發(fā)廣播,那么接受廣播后的代碼就在這個(gè)線程執(zhí)行粉捻。
優(yōu)化:那么如果代碼中存在很多這種發(fā)送廣播刷新UI的時(shí)候礁遣,豈不是每次發(fā)的時(shí)候都要判斷一下是不是在主線程,比較麻煩肩刃。所以給刷新UI的代碼加上GCD主線程執(zhí)行祟霍,也能達(dá)到同樣的效果。
延伸:Notification是iOS中常用的通信方式盈包,那么其他方式如KVO沸呐、delegate一樣也會(huì)存在這種問(wèn)題,所以在異步加載數(shù)據(jù)刷新界面的時(shí)候都需要在主線程進(jìn)行呢燥。