在Swift中将NSData转换为Data,现在当我尝试将字节转换为[UInt]时发生崩溃

时间:2018-12-24 23:45:50

标签: objective-c swift pointers

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

SELECT CONCAT('€ ', FORMAT(IFNULL(SUM(mutations),0),2)) AS total
FROM scu_statement 
WHERE type='2'

这是我将其转换为Swift的方式:

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])];

有人知道我在做什么错吗?据我所知,我已正确地从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,但似乎我弄错了。

1 个答案:

答案 0 :(得分:0)

您崩溃的原因是此表达式:

bytes : UnsafePointer<[UInt]>

您假设数据代表一系列UInt。因此,指向数据开头的指针并不是不安全的指向[UInt](UInt的 array )的指针。它是指向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
    }
}