當前位置:
首頁 > 知識 > Swift中由找不到removeAll(where:)方法引起的連鎖反應(上)

Swift中由找不到removeAll(where:)方法引起的連鎖反應(上)

提示:本篇博文涉及到第三方庫Eureka,但核心思想在於Swift內部數據處理的推斷,不了解Eureka並不影響對本文的理解。Eureka只不過是對UITableView的便捷包裝而已,需要進一步了解Eureka的童鞋可以觀賞本貓Eureka學習系列博文。

核心代碼

section.removeAll {baseRow in

if let habitRow = baseRow as? HabitRow{

let idxPath = habitRow.indexPath!

return willRemoveIdxPaths.contains(idxPath)

}

return false

}

1

2

3

4

5

6

7

以上代碼片段的功能是刪除willRemoveIdxPaths隊列中對應的所有Rows。Row對應著一個Cell,Cell是Eureka中對UITableViewCell的包裝。那麼上面實際是將指定的Cells從UITableView中刪除。

核心問題

為什麼要用removeAll(where:)方法去刪除Rows,而不是用遍歷刪除的方法?比如說如下代碼:

for idxPath in willRemoveIdxPaths{

section.remove(at: idxPath.row)

}

1

2

3

原因是:遍歷刪除的方法在刪除多個Row時行為並不正確!

道理很簡單,當刪除掉一個Row後,其他Row的索引會發生變化,那麼其他待刪除的索引就會指向錯誤的Row。

舉個栗子:比如我要一次性刪除0和1位置兩個Row,但是當我刪除掉0位置的Row後,原來1位置的Row會上升到位置0,原來2位置的Row會上升到位置1;接下來我再刪除位置1的Row,實際刪除的卻是原來位置2的Row。

那麼問題又來了:為什麼removeAll(where:)可以正確刪除多個Row?

這個答案先不揭曉,它會隨著本貓的敘述逐漸明朗,現在暫且相信本貓它可以滿足一次性刪除多個Row的功能。

使用場景一 :Xcode 10+ Swift 4.2

刪除代碼工作良好

使用場景二 :Xcode 9.2 Swift 4.1

提示找不到removeAll(where:)方法!!!

提示找不到removeAll(where:)方法!!!

提示找不到removeAll(where:)方法!!!

但是removeAll()方法是存在的!

為了能夠更好地解釋為什麼找不到這個方法,我們首先要搞清楚,這個方法是從哪裡來的?

線索一 removeAll(where:) Where Are You From???

從Apple官網查詢一下:

https://developer.apple.com/documentation/swift/rangereplaceablecollection/3018275-removeall

為了方便討論,直接看搜索結果

Swift中由找不到removeAll(where:)方法引起的連鎖反應(上)

打開今日頭條,查看更多精彩圖片

Swift中由找不到removeAll(where:)方法引起的連鎖反應(上)

從上面我們了解到2點:

該方法只在Xcode 10.0+才可以使用

該方法是RangeReplaceableCollection協議的一部分

這是一個好的開頭,不是么?(這是原創文章,雖然這段話很像翻譯的…)

線索二 Section到底是什麼?為什麼包含removeAll方法?

因為Eureka是開源的,所以這個問題的答案頗為簡單:它幾乎什麼都不是!

它不繼承於任何類,包含的所有Row或Cell你幾乎都不能直接操作;它內部實現了一個KVOWrapper類,用於處理Row各種修改的細節。

那麼問題又來了:它為什麼可以有removeAll或removeAll(where:)方法?

從線索一中不難推斷答案:因為它遵守RangeReplaceableCollection協議!

所以它包含集合操作的N種方法:

Swift中由找不到removeAll(where:)方法引起的連鎖反應(上)

看到這大家都應該明了:

Xcode 9.2中之所以找不到removeAll(where:)方法是因為Xcode 9.2(或者Swift 4.1)中的RangeReplaceableCollection協議沒有這個方法!

可是在查看Section類源代碼時發現,它即使在Xcode 10.0中也沒有實現removeAll(where:)方法,所以我們又可以得出推論:

removeAll(where:)方法是RangeReplaceableCollection協議擴展自動為你生成的!你可以免費使用這個方法,只要你遵守RangeReplaceableCollection協議,且在Swift 4.2+中。

更多問題 Come On!!!

至此為止,我們得到了一些線索,有了一些新的認識。但是還有兩個重要問題沒有解決:

1.為什麼免費的removeAll(where:)方法可以做到一次性正確刪除多個Row?它和遍歷刪除到底有什麼不同?

2.我們如何在Swift 4.1中自己實現這個方法?

我們下回分解.

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Jquery 初始化
markdown常用語法

TAG:程序員小新人學習 |