你如何在Swift 3中使用Data.withUnsafeMutbleBytes?

时间:2017-02-07 16:42:40

标签: ios swift

我正在尝试使用Realm文档中的代码:

var key = Data(count: 64)
_ = key.withUnsafeMutableBytes { bytes in
    SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
}

就其本身而言,这将编译。但是,由于withUnsafeMutableBytes用闭包完成,而不是这种类型的代码流:

var key = Data(count: 64)
_ = key.withUnsafeMutableBytes { bytes in
    SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
}
// do something using the encryption key

我想将其更改为:

var key = Data(count: 64)
_ = key.withUnsafeMutableBytes { bytes in
    SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
    // do something using the encryption key
}

但是我不能在没有开始出错的情况下向闭包中添加任何其他东西,例如它不可能只是简单地添加一个print语句:

    var key = Data(count: 64)
    _ = key.withUnsafeMutableBytes { bytes in
        SecRandomCopyBytes(kSecRandomDefault, 64, bytes)
        print("WTF!")
    }

会出现此错误:

enter image description here

如果我试图摆脱_,那么这个错误:

enter image description here

我找到了这个帖子https://forums.developer.apple.com/thread/51439

但是在尝试了那个没有编译实际编译的线程之后,所以在应用XCode自动更正之后,我只是接着一个接一个地接着一个接一个地发出错误并且让我疯狂。

2 个答案:

答案 0 :(得分:1)

忽略SecRandomCopyBytes部分,整体语法为:

var key = Data(count: 64)
key.withUnsafeMutableBytes { (ptr:UnsafeMutablePointer<UInt8>) -> Void in
    print("here")
}

SecRandomCopyBytes似乎没有任何重大差异:

var key = Data(count: 64)
key.withUnsafeMutableBytes { (ptr:UnsafeMutablePointer<UInt8>) -> Void in
    SecRandomCopyBytes(kSecRandomDefault, 64, ptr)
    print("here")
}

当然,这可能不是您的最终代码,但重点是它编译并允许您继续进一步开发代码。 - 实际上,只是为了笑,我尝试了以下,看看我们是否真的用随机字节填充数据,它似乎工作正常:

    var key = Data(count: 64)
    key.withUnsafeMutableBytes { (ptr:UnsafeMutablePointer<UInt8>) -> Void in
        _ = SecRandomCopyBytes(kSecRandomDefault, 64, ptr)
    }
    for b in key {print(b)}

请注意使用_ =来取消有关未使用结果的警告。

答案 1 :(得分:0)

对我来说,在工作之前先声明一个计数常数:

func generateRandomBytes() -> String? {
        var keyData = Data(count: 48)
        let count = keyData.count
        let result = keyData.withUnsafeMutableBytes {
            (mutableBytes: UnsafeMutablePointer<UInt8>) -> Int32 in
            SecRandomCopyBytes(kSecRandomDefault, count, mutableBytes)
        }
        if result == errSecSuccess {
            return keyData.base64EncodedString()
        } else {
            print("Problem generating random bytes")
            return nil
        }
    }