【问题标题】:Converted NSData to Data in Swift, and now when I try to cast bytes to [UInt] I get a crash在 Swift 中将 NSData 转换为 Data,现在当我尝试将字节转换为 [UInt] 时,我遇到了崩溃
【发布时间】:2023-03-21 04:29:02
【问题描述】:

这是旧的 Objective C 代码(令牌是 NSData):

const unsigned *tokenBytes = [credentials.token bytes];
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                      ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                      ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                      ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];

这是我将它转换为 Swift 的方法:

let tokenBytes = credentials.token.withUnsafeBytes { (bytes: UnsafePointer<[UInt]>) -> [UInt] in
        return bytes[0] // Crash here
    }

    let hexToken = String(format: "%08x%08x%08x%08x%08x%08x%08x%08x",
                          UInt(bigEndian: tokenBytes[0]), UInt(bigEndian: tokenBytes[1]),
                          UInt(bigEndian: tokenBytes[2]), UInt(bigEndian: tokenBytes[3]),
                          UInt(bigEndian: tokenBytes[4]), UInt(bigEndian: tokenBytes[5]),
                          UInt(bigEndian: tokenBytes[6]), UInt(bigEndian: tokenBytes[7])
    )

有谁知道我做错了什么?据我所知,我正确地从bytes 转换为withUnsafeBytes,但似乎我错了。

【问题讨论】:

  • 您登录bytes 看看里面有什么? print(bytes[0]) - 我敢打赌它未定义
  • 只是一堆数字,不确定是否有帮助。老实说,我在这里已经脱离了我的联盟,对字节/低级别的东西没有太多经验。编辑:刚刚看到你想让我打印下标。我会这样做并回复你。
  • 粘贴print(bytes)print(bytes[0])的输出
  • 0x00000002815f6cb0 为前者,字节崩溃[0]
  • 是的,所以我认为您不能将 0x00000002815f6cb0 视为一个数组,它是一个 UnsafePointer,我对 swift 不是很熟悉,但它指向内存中的一个位置。

标签: objective-c swift pointers


【解决方案1】:

你崩溃的原因是这个表达式:

bytes : UnsafePointer<[UInt]>

您假设数据代表一系列 UInt。因此,指向数据开头的指针不像指向[UInt](UInt 的数组)的不安全指针;它是指向 UInt 的不安全指针,即系列中的第一个。你应该说:

bytes : UnsafePointer<UInt>

崩溃了。现在让我们谈谈您在这里最想做的事情。

我不确定字符串格式应该做什么,但我确实理解ntohl 的想法是保证一些 C 长整数(32 位)的字节序。所以我将省略字符串格式部分,只讨论如何将接收到的 C long int 流转换为 Data 并反转 long int 的字节序。

假设d 是一个可变数据(即用var 声明)。然后,假设它代表一系列 UInt32 little-endian 值,并且您想将它们转换为 big-endian,您会说:

let ct = d.count/4
d.withUnsafeMutableBytes{
    (ptr:UnsafeMutablePointer<UInt32>) in
    for ix in 0..<ct {
        ptr[ix] = ptr[ix].bigEndian
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-06
    • 2012-08-27
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多