iOS TableView 運(yùn)行原理及數(shù)據(jù)刷新的坑

場(chǎng)景示意圖.png
場(chǎng)景是這樣的:
  1. APP首頁(yè)是一個(gè)UITableView列表,數(shù)據(jù)源設(shè)置為全局變量dataList,點(diǎn)擊則跳轉(zhuǎn)第2頁(yè)詳情頁(yè)
  2. 在詳情頁(yè)中刷新dataList(元素個(gè)數(shù)未改變),并通知首頁(yè)reloadData刷新UI
  3. 然后刪除dataList一個(gè)元素,并通知首頁(yè)列表刷新reloadData,導(dǎo)致程序崩潰并報(bào)

*** Terminating app due to uncaught exception 'NSRangeException', reason:
'*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

錯(cuò)誤

此bug被測(cè)試提出后,筆者研究了半天,看似正常的刷新tableView列表的邏輯怎么會(huì)出錯(cuò)呢,最后發(fā)現(xiàn)原來(lái)是對(duì)UITableView控價(jià)的運(yùn)行機(jī)制沒有深刻了解,謹(jǐn)以此文分享給大家,以免重復(fù)掉坑。

1. UITableView的視圖加載邏輯

  • load 視圖
    viewDidLoad
    viewWillAppear:

  • 加載完數(shù)據(jù)源之前 多次順序執(zhí)行以下方法:
    numberOfSectionsInTableView:
    numberOfRowsInSection:

  • 視圖在屏幕上展示
    viewDidAppear:

2. 已加載完數(shù)據(jù)源開始刷新

  • 刷新
    reloadData

  • 多次執(zhí)行以下方法:
    numberOfSectionsInTableView:
    numberOfRowsInSection:
    heightForRowAtIndexPath:

  • 根據(jù)數(shù)據(jù)源元素?cái)?shù)執(zhí)行相應(yīng)的次數(shù)
    cellForRowAtIndexPath:

因?yàn)閺?fù)用池的緣故,分以下2種情況:

  • 元素個(gè)數(shù)<頁(yè)面容納的行數(shù),執(zhí)行次數(shù)=元素個(gè)數(shù)
  • 元素個(gè)數(shù)>頁(yè)面容納的行數(shù),執(zhí)行次數(shù)=頁(yè)面容納的行數(shù)

3. 在詳情頁(yè)刷新了數(shù)據(jù)源和列表后返回首頁(yè)

  • 視圖將要展示在屏幕上
    viewWillAppear:

  • 關(guān)鍵點(diǎn)、坑點(diǎn)
    cellForRowAtIndexPath:

注意:此處首頁(yè)-->詳情頁(yè)是在Navi棧里push的:

  • 若在詳情頁(yè)沒有對(duì)首頁(yè) tableView 列表的數(shù)據(jù)源和列表進(jìn)行刷新,則pop回首頁(yè)時(shí),首頁(yè)列表不會(huì)自行刷新(即需 reloadData 方法手動(dòng)刷新)
  • 若在 詳情頁(yè) 已通過(guò) 協(xié)議通知 回調(diào)對(duì) 首頁(yè) tableView 列表的數(shù)據(jù)源和列表進(jìn)行刷新,則pop回首頁(yè)時(shí),首頁(yè)列表一開始會(huì)自行繞過(guò)numberOfRowsInSection: 而進(jìn)入 cellForRowAtIndexPath: 方法執(zhí)行,之后再根據(jù)通知 reloaData 手動(dòng)刷新。而此時(shí)首頁(yè)列表默認(rèn)是按照push之前的數(shù)據(jù)源元素?cái)?shù)執(zhí)行,此前詳情頁(yè)已刪除數(shù)據(jù)源中的一個(gè)元素,在此時(shí)數(shù)據(jù)源已改變,自然會(huì)產(chǎn)生數(shù)組越界問(wèn)題

4. 解決問(wèn)題

實(shí)際上只要了解了整個(gè)過(guò)程中 tableView 列表控件的一系列回調(diào)方法運(yùn)行原理及邏輯,以上問(wèn)題就迎刃而解了。

解決示例.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述在iOS開發(fā)中UITableView可以說(shuō)是使用最廣泛的控件,我們平時(shí)使用的軟件中到處都可以看到它的影子,類似...
    liudhkk閱讀 9,282評(píng)論 3 38
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,036評(píng)論 4 61
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • 05號(hào)果果 今天,向大家推薦一本很有現(xiàn)實(shí)意義的小說(shuō)《解憂雜貨店》?!督鈶n雜貨店》是日本作家東野圭吾寫作的奇幻...
    簡(jiǎn)小樓閱讀 258評(píng)論 6 3
  • ?01 男生需要哭泣 但是從不輕易在人前哭泣 02 男生真的不在乎女生 是否真的能看懂體育比賽 盡管他們聲稱能有 ...
    她他社閱讀 788評(píng)論 0 0

友情鏈接更多精彩內(nèi)容