Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 范围内的快速变异数据_Swift_Nsdata_Unsafe Pointers - Fatal编程技术网

Swift 范围内的快速变异数据

Swift 范围内的快速变异数据,swift,nsdata,unsafe-pointers,Swift,Nsdata,Unsafe Pointers,我正在构建一个数据对象,其外观如下: struct StructuredData { var crc: UInt16 var someData: UInt32 var someMoreData: UInt64 // etc. } aMethod(&param) 我正在运行一个CRC算法,它将从字节2开始,进程长度为12 返回CRC时,它必须存在于数据对象的开头。在我看来,我的选择是: 生成一个不包含CRC的数据对象,对其进行处理,然后构建另一个包含CRC的数据对象(这

我正在构建一个
数据
对象,其外观如下:

struct StructuredData {
  var crc: UInt16
  var someData: UInt32
  var someMoreData: UInt64
  // etc.
}
aMethod(&param)
我正在运行一个CRC算法,它将从字节2开始,进程长度为12

返回CRC时,它必须存在于
数据
对象的开头。在我看来,我的选择是:

  • 生成一个不包含CRC的
    数据
    对象,对其进行处理,然后构建另一个包含CRC的
    数据
    对象(这样我现在拥有的CRC值将位于
    数据
    对象的开头)


  • 生成数据对象以包含一个零输出的CRC,然后在范围内对数据进行变异
    [0..我找到了它。实际上,我遇到了一个语法错误,这让我感到难以置信,因为我以前没有看到过

    答案如下:

    data.replaceSubrange(0..<2, with: UnsafeBufferPointer(start: &self.crc, count: 1))
    

    data.replaceSubrange(0..我找到了答案。我实际上遇到了一个语法错误,这让我感到难以置信,因为我以前从未见过这个错误

    答案如下:

    data.replaceSubrange(0..<2, with: UnsafeBufferPointer(start: &self.crc, count: 1))
    

    data.replaceSubrange(0..

    data.replaceSubrange(0..<2, with: UnsafeBufferPointer(start: &self.crc, count: 1))
    
    • Swift分配一些大小足以容纳
      param
      内容的区域

    • param
      复制到区域中,(复制到)

    • 通过传递区域的地址调用方法

    • 从调用返回时,将区域内容复制回
      param
      (复制)

    在许多情况下,Swift仅通过传递
    param
    的实际地址来优化步骤(即使在
    -Onone
    设置中也可能发生),但没有明确的文档记录

    因此,当
    inout
    参数传递给
    UnsafeBufferPointer
    的初始值设定项时,
    UnsafeBufferPointer
    接收的地址可能指向一个临时区域,该临时区域将在初始值设定项完成后立即释放

    因此,
    replaceSubrange(u:with:)
    可以将已发布区域中的字节复制到
    数据中

    我相信第一个代码在这种情况下会起作用,因为
    crc
    是结构的一个属性,但是如果有一个简单而安全的替代方法,您最好避免使用不安全的方法


    补充布兰登·曼泽伊自己的回答

    data.append(UnsafeBufferPointer(start: &self.crcOfRecordData, count: 1))
    
    按照上述含义使用safe。出于上述相同原因,这是不安全的

    我会这样写:

    data.append(Data(bytes: &self.crcOfRecordData, count: MemoryLayout<UInt16>.size))
    
    withUnsafeBytes(of: &self.crcOfRecordData) {urbp in
         data.append(urbp.baseAddress!.assumingMemoryBound(to: UInt8.self), count: MemoryLayout<UInt16>.size)
    }
    
    let uint32Data = Data(bytes: &self.someData, count: MemoryLayout<UInt32>.size)
    

    注释中未提及这一点,但根据上述安全的含义,以下行不安全

    同样的原因

    我会这样写:

    data.append(Data(bytes: &self.crcOfRecordData, count: MemoryLayout<UInt16>.size))
    
    withUnsafeBytes(of: &self.crcOfRecordData) {urbp in
         data.append(urbp.baseAddress!.assumingMemoryBound(to: UInt8.self), count: MemoryLayout<UInt16>.size)
    }
    
    let uint32Data = Data(bytes: &self.someData, count: MemoryLayout<UInt32>.size)
    
    让uint32Data=Data(字节:&self.someData,计数:MemoryLayout.size)
    

    尽管如此,可观察到的意外行为可能会在一些非常有限的条件下发生,并且概率非常小

    只有满足以下两个条件时,才会发生这种行为:

  • Swift编译器生成非优化的复制入复制出代码

  • 在非常窄的时间段之间,由于时间区域被释放,直到
    append
    方法(或
    Data.init
    )完成对整个内容的复制,因此该区域被修改以供其他用途

  • 条件#1仅在当前实施Swift的有限情况下变为真

    只有在多线程环境中才会出现条件#2(尽管如此,苹果的框架使用了许多隐藏线程,正如你可以在Xcode的调试器中找到的那样)

    事实上,我没有看到任何关于上述不安全案例的问题,我的保险箱可能有点过分了

    但其他安全代码并没有那么复杂,是吗?
    在我看来,您最好习惯于使用所有情况下的安全代码。

    我不建议使用以下方法对数据进行变异:

    data.replaceSubrange(0..<2, with: UnsafeBufferPointer(start: &self.crc, count: 1))
    
    • Swift分配一些大小足以容纳
      param
      内容的区域

    • param
      复制到区域中,(复制到)

    • 通过传递区域的地址调用方法

    • 从调用返回时,将区域内容复制回
      param
      (复制)

    在许多情况下,Swift仅通过传递
    param
    的实际地址来优化步骤(即使在
    -Onone
    设置中也可能发生),但没有明确的文档记录

    因此,当
    inout
    参数传递给
    UnsafeBufferPointer
    的初始值设定项时,
    UnsafeBufferPointer
    接收的地址可能指向一个临时区域,该临时区域将在初始值设定项完成后立即释放

    因此,
    replaceSubrange(u:with:)
    可以将已发布区域中的字节复制到
    数据中

    我相信第一个代码在这种情况下会起作用,因为
    crc
    是结构的一个属性,但是如果有一个简单而安全的替代方法,您最好避免使用不安全的方法


    补充布兰登·曼泽伊自己的回答

    data.append(UnsafeBufferPointer(start: &self.crcOfRecordData, count: 1))
    
    按照上述含义使用safe。出于上述相同原因,这是不安全的

    我会这样写:

    data.append(Data(bytes: &self.crcOfRecordData, count: MemoryLayout<UInt16>.size))
    
    withUnsafeBytes(of: &self.crcOfRecordData) {urbp in
         data.append(urbp.baseAddress!.assumingMemoryBound(to: UInt8.self), count: MemoryLayout<UInt16>.size)
    }
    
    let uint32Data = Data(bytes: &self.someData, count: MemoryLayout<UInt32>.size)
    

    注释中未提及这一点,但根据上述安全的含义,以下行不安全

    同样的原因

    我会这样写:

    data.append(Data(bytes: &self.crcOfRecordData, count: MemoryLayout<UInt16>.size))
    
    withUnsafeBytes(of: &self.crcOfRecordData) {urbp in
         data.append(urbp.baseAddress!.assumingMemoryBound(to: UInt8.self), count: MemoryLayout<UInt16>.size)
    }
    
    let uint32Data = Data(bytes: &self.someData, count: MemoryLayout<UInt32>.size)
    
    让uint32Data=Data(字节:&self.someData,计数:MemoryLayout.size)
    

    尽管如此,可观察到的意外行为可能会在一些非常有限的条件下发生,并且概率非常小

    只有满足以下两个条件时,才会发生这种行为:

  • Swift编译器生成非优化的复制入复制出代码

  • 在非常窄的时间段之间,由于时间区域被释放,直到
    append
    方法(或
    Data.init
    )完成对整个内容的复制,因此该区域被修改以供其他用途

  • 条件#1仅为真