【iOS 開發(fā)】tableView updates 對比 reloadData

Paste_Image.png

如圖有一個 TableView,每行顯示這一行是第幾行,現(xiàn)在我希望每按一次 update 按鈕,就動態(tài)地在下方加兩行。那么簡單粗暴的做法是 ,更改數(shù)據(jù)源,然后刷新一下列表:

// tableData = ["0", "1", "2", "3"]
@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    tableView.reloadData()
}

用膝蓋想也知道,這會使得前四行沒有被改動的地方也被刷新一遍,帶來了不必要的性能損耗。
好一點的做法是下面這樣的:

// tableData = ["0", "1", "2", "3"]
@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    tableView.beginUpdates()
    let indexPaths = [IndexPath(row: tableData.count-2, section: 0), IndexPath(row: tableData.count-1, section: 0)]
    tableView.insertRows(at: indexPaths, with: UITableViewRowAnimation.automatic)
    tableView.endUpdates()
}

與上面相比,這樣做使得 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法被少調(diào)用了四次。

這里 beginUpdatesendUpdates 方法的作用是,將這兩條語句之間的對 tableView 的 insert/delete 操作聚合起來,然后同時更新 UI。鑒于我這里只進(jìn)行了一次 insert 操作,把這兩條語句去掉也沒事,但是出于規(guī)范還是應(yīng)該寫上,因為假如習(xí)慣不寫,下面這樣的代碼會運行時崩潰:

@IBAction func update(_ sender: AnyObject) {
    tableData.append("\(tableData.count)")
    tableData.append("\(tableData.count)")
    //        tableView.beginUpdates()
    tableView.insertRows(at: [IndexPath(row: tableData.count-2, section: 0)], with: UITableViewRowAnimation.automatic)
    tableView.insertRows(at: [IndexPath(row: tableData.count-1, section: 0)], with: UITableViewRowAnimation.automatic)
    //        tableView.endUpdates()
}

因為第一次 insert 之后,當(dāng)前 row 的總數(shù)量在 UI 上試圖 4 變成 5,然而數(shù)據(jù)源是 6,它會檢查使用者對 tableView 的 UI 操作,最后是不是和 numberOfRows 方法獲取的值相對應(yīng)。

總結(jié)

numberOfRows 方法調(diào)用: 都只調(diào)用一次 numberOfRows 方法

cellForRow 方法調(diào)用次數(shù): reloadData 會為當(dāng)前顯示的所有cell調(diào)用這個方法,updates 只會為新增的cell調(diào)用這個方法
cellForRow 方法調(diào)用時間: reloadData 會在 numberOfRows 方法調(diào)用后的某一時間異步調(diào)用 cellForRow 方法,updates 會在 numberOfRows 方法調(diào)用后馬上調(diào)用 cellForRow 方法

reloadData 方法缺陷: 帶來額外的不必要開銷,缺乏動畫
updates 方法缺陷:deleteRows 不會調(diào)用 cellForRow 方法,可能導(dǎo)致顯示結(jié)果與數(shù)據(jù)源不一致;需要手動保證 insertRows、deleteRows 之后,row 的數(shù)量與 numberOfRows 的結(jié)果一致,否則會運行時崩潰


部分文章中沒有寫,總結(jié)提到了的部分放在完整 demo 里面了:demo Github 地址

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

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

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