請記住,您收到的MutableRandomAccessSlice
是值類型,而不是引用類型。它只是意味着,如果你喜歡,你可以修改它,但它沒有任何關係的事情,你切出來的:
let x = Data(bytes: [1,2,3]) // <010203>
var y = x[0...1]
y[0] = 2
x // <010203>
如果您在code看,你會注意到,目的是用來返一個自定義切片類型:
public subscript(bounds: Range<Index>) -> MutableRandomAccessSlice<Data> {
get {
return MutableRandomAccessSlice(base: self, bounds: bounds)
}
set {
// Ideally this would be:
// replaceBytes(in: bounds, with: newValue._base)
// but we do not have access to _base due to 'internal' protection
// TODO: Use a custom Slice type so we have access to the underlying data
let arrayOfBytes = newValue.map { $0 }
arrayOfBytes.withUnsafeBufferPointer {
let otherData = Data(buffer: $0)
replaceBytes(in: bounds, with: otherData)
}
}
}
也就是說,自定義切片對於接受數據的函數仍然是不可接受的。但是,這與其他類型一致,如Array,它切片到ArraySlice,而ArraySlice不能在需要Array的地方傳遞。這是設計的(對於Data也可能出於同樣的原因)。關注的是,一個切片「釘住」所有支持它的內存。所以如果你從兆字節的數據中取出一個3字節的片並將它存儲在一個ivar中,那麼整個兆字節就不得不四處閒逛。理論(根據Swift開發者的說法)是數組可能很大,所以你需要小心切分它們,而字符串通常要小得多,所以String可以切成一個String。
以我迄今爲止的經驗,你一般都想要subdata(in:)
。我對它的實驗是它在速度上與切片非常相似,所以我相信它仍然是在寫入時拷貝的(但它似乎並沒有在我的初始測試中固定內存)。儘管如此,我只在Mac上測試過。 iOS設備上可能存在更顯着的性能差異。
這是非常明確和簡潔的答案! –