# Array的startIndex的崩溃分析

·  阅读 329

### 崩溃1和分析

``````//代码
private func mergeSortSlice(_ myArraySlice: ArraySlice<Element>) -> ArraySlice<Element> {
if myArraySlice.count < 2 {
return myArraySlice
}else {
let midIndex = myArraySlice.count / 2
print("\(midIndex) -- \(myArraySlice.startIndex) -- \(myArraySlice.endIndex)")
let leftSlice = myArraySlice[myArraySlice.startIndex..<midIndex]
let rightSlice = myArraySlice[midIndex..<myArraySlice.endIndex]

print(leftSlice)
print(rightSlice)
let slice1 = mergeSortSlice(leftSlice)
print(slice1)
let slice2 = mergeSortSlice(rightSlice)
print(slice2)
return merge(slice1, slice2)
}
}

//打印
2 -- 0 -- 4
[8, 4]
[7, 3]
1 -- 0 -- 2
[8]
[4]
[8]
[4]
[4, 8]
1 -- 2 -- 4
Fatal error: Can't form Range with upperBound < lowerBound

//分析
myArraySlice是方法传进来的实参，它的小标不是从0开始的，所以myArraySlice.startIndex..<midIndex，出现了左边的值比右边的值还大的情况。

### 崩溃2和分析

``````//代码
let midIndex = myArraySlice.count / 2
print("\(midIndex) -- \(myArraySlice.startIndex) -- \(myArraySlice.endIndex)")
let leftSlice = myArraySlice[0..<midIndex]
let rightSlice = myArraySlice[midIndex..<myArraySlice.count]
print(leftSlice)
print(rightSlice)

//打印
2 -- 0 -- 4
[8, 4]
[7, 3]
1 -- 0 -- 2
[8]
[4]
[8]
[4]
[4, 8]
1 -- 2 -- 4
Fatal error: ArraySlice index is out of range (before startIndex)

//分析

### 解决的code

``````//代码
let midIndex = myArraySlice.count / 2
print("\(midIndex) -- \(myArraySlice.startIndex) -- \(myArraySlice.endIndex)")
let newSlice = ArraySlice.init(myArraySlice)
print("\(midIndex) -- \(newSlice.startIndex) -- \(newSlice.endIndex)")
let leftSlice = newSlice[0..<midIndex]
let rightSlice = newSlice[midIndex..<newSlice.count]
print(leftSlice)
print(rightSlice)

//打印
2 -- 0 -- 4
2 -- 0 -- 4
[8, 4]
[7, 3]
1 -- 0 -- 2
1 -- 0 -- 2
[8]
[4]
[8]
[4]
[4, 8]
1 -- 2 -- 4
1 -- 0 -- 2
[7]
[3]
[7]
[3]
[3, 7]
[3, 4, 7, 8]

//分析

### 更好解决的code

``````//代码
let midIndex = (myArraySlice.startIndex + myArraySlice.endIndex) / 2
print("\(midIndex) -- \(myArraySlice.startIndex) -- \(myArraySlice.endIndex)")
let leftSlice = myArraySlice[myArraySlice.startIndex..<midIndex]
let rightSlice = myArraySlice[midIndex..<myArraySlice.endIndex]

### 总结

• 对数组做切片后，局部切片的下标值不变，虽然长度变小了，但是不能从下标0取值或者在进行切片。如果要用下标0..<(count/2)和(count/2)..<count来平分当前切片，需要新建一个当前切片的副本，那么这个副本的下标就从0开始了。

• 如果用startIndex和endIndex从数组取值，这2个值还是在原数组中的下标，所以计算当前切片长度中间的下标值的时候，要用这2个下标的和除以2。对当前切片在进行更小的平分切片时，可以用startIndex、中间下标和endIndex来切分。

iOS