在Data实例上使用[]运算符时出现异常

问题描述 投票:2回答:1

这个小Swift片段在最后一次赋值时崩溃Xcode 9.2游戏,虽然缓冲区仍然保存23个字节。任何想法为什么会这样?

import Cocoa

var str = "01234567890123456789012345678901234567"
var buffer = Data()

if let data = str.data(using: .utf8) {
   buffer.append(data)
   buffer = buffer[15..<38]
   buffer = buffer[2..<23]
}
swift
1个回答
2
投票

看起来这是由SDK错误或编译器优化引起的,两者都试图避免不必要的数据副本(也就是写时复制)。在有问题的行上设置断点并检查buffer会显示如下:

enter image description here

因此缓冲区指向相同的数据存储,但是不同的切片,并且尝试在切片外部访问会导致崩溃。

将有问题的行更改为buffer = buffer[17..<38]会导致崩溃消失。

我不知道为什么按范围下标导致Data可能导致崩溃,如果在代码的另一个(可能不相关的)部分中使用,而不知道它们正在处理切片。其他集合,如Array有专用的切片类型,您可以期望它们具有各种有效的索引。

这是一个支持上述想法的天真例子:

func printFirstByte(of data: Data) {
    print(data[0])
}

let str = "01234567890123456789012345678901234567"
if let data = str.data(using: .utf8) {
    printFirstByte(of: data[15..<38]) // this call crashes
}

另一方面,我们确实在startIndex类型上有endIndexData属性,但是这使得使用Data实例变得更加困难,因为我们需要在将Data切片发送到旧之前将其置零。不知道此行为的代码。

© www.soinside.com 2019 - 2024. All rights reserved.