1.相遇
有個(gè)業(yè)務(wù)需求,把表格中的數(shù)據(jù)整合到一個(gè)數(shù)組中嚷闭,如下
Name | Age | Item1 | Item2 | Item3 | Country |
---|---|---|---|---|---|
Jack | 21 | 32 | 43 | null | China |
Tom | 23 | 83 | 67 | 75 | US |
整合后的結(jié)果是這樣
[
{
"Name": "Jack",
"Age": 21,
"score": [
{
"Item1": 32
},
{
"Item2": 43
}
],
"Country": "China"
},
{
"Name": "Tom",
"Age": 23,
"score": [
{
"Item1": 83
},
{
"Item2": 67
},
{
"Item3": 75
}
],
"Country": "US"
}
]
有個(gè)中間的狀態(tài)勤众,就是把一條記錄整合出來之后,取中間的幾個(gè)元素作為一個(gè)整體花吟,所以需要把中間的幾個(gè)數(shù)據(jù)切片到一個(gè)新的數(shù)組中秸歧。
之前在學(xué)習(xí)Swift的時(shí)候,了解過一下數(shù)組的用法衅澈,以為是非常了解了键菱,實(shí)則不然。
2.對(duì)于切片數(shù)組的 subscript 今布,你了解多少经备?
一個(gè)簡單例子
let array = ["A", "B", "C", "D"]
let slicedArray = array[1..<3]
print(slicedArray.count) // 2
print(slicedArray[0]) // error
WHY?
明明數(shù)組中有兩個(gè)元素部默,但是為什么用subscript訪問侵蒙,卻報(bào)錯(cuò)呢?
還有
let slicedArray String = slicedArray.reduce("start: ") { (acc, item) -> String in
"\(acc)\(item)"
}
print(slicedString) // start: BC
很明顯這個(gè)"數(shù)組"中是有數(shù)據(jù)的呀傅蹂,怎么就是取不出來呢纷闺???????
3.startIndex & endIndex
slicedArray 的 startIndex 和 endIndex 是多少呢?
print(slicedArray.startIndex) // 1 instead 0
print(slicedArray.endIndex) // 3
所以份蝴,在用[0]訪問slicedArray的時(shí)候单鹿,其實(shí)是越界的 out of bounds !!!!
4.怎么解決這個(gè)問題
不去詳細(xì)的解釋為什么佛玄,這個(gè)跟swift對(duì)數(shù)組的設(shè)計(jì)理念相關(guān)樊诺,copy-on-write眠屎,目的之一提高性能。另外请敦,一個(gè)需要注意的地方镐躲,就是在官方的開發(fā)文檔上,有這樣一段說明:
Warning: Long-term storage of
ArraySlice
instances is discouraged.
Because a
ArraySlice
presents a view onto the storage of some larger array even after the original array's lifetime ends, storing the slice may prolong the lifetime of elements that are no longer accessible, which can manifest as apparent memory and object leakage. To prevent this effect, useArraySlice
only for transient computation.
警告:不建議長時(shí)間的存儲(chǔ)
ArraySlice
實(shí)例
由于一個(gè)
ArraySlice
實(shí)例呈現(xiàn)的是某個(gè)比較大的數(shù)組上的一個(gè)視圖侍筛。如果這個(gè)原始數(shù)組已經(jīng)結(jié)束了其生命周期萤皂,存儲(chǔ)這個(gè)切片實(shí)例可能會(huì)延長那些不能再被訪問的數(shù)組元素的存活時(shí)間,這就造成了明顯的內(nèi)存和對(duì)象泄露匣椰。為了防止這個(gè)影響的發(fā)生裆熙,只在臨時(shí)性的計(jì)算時(shí),使用ArraySlice
。
兩個(gè)方案解決這個(gè)問題:
-
違背swift的設(shè)計(jì)原則如果想長期的保留這個(gè)切片對(duì)象入录,請(qǐng)轉(zhuǎn)化成數(shù)組直接創(chuàng)建一個(gè)新的數(shù)組變量
let lastedArray = Array(array[1..<3])
print(lastedArray.startIndex) // 0
print(lastedArray.endIndex) // 2
print(lastedArray[0]) // B
- 使用數(shù)組的屬性
startIndex
,endIndex
combinedArray[combinedArray.startIndex] // B
combinedArray[combinedArray.startIndex.advancedBy(1)] // C