【发布时间】:2019-03-27 18:30:14
【问题描述】:
我已更新到 swift 5,但我使用的依赖项之一无法在 swift 5 中编译。我已修复它,但现在我在整个文件中收到 350 多个弃用警告。它们都与此类似:
withUnsafeMutableBytes已弃用:改用withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R
这是代码片段(基本上只是调用 c 库的函数):
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr)
}
作为参考,上面的crypto_generichash_keybytes()只返回一个size_t,crypto_generichash_keygen的签名是void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]);。
我发现(如this answer 所述)解决此问题的方法应该是调用 kPtr.baseAddress:
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { kPtr in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)
}
因为应该使用withUnsafeMutableBytes<ResultType> 变体而不是已弃用的withUnsafeMutableBytes<ResultType, ContentType>。但是,这反而会导致错误
“UnsafeMutablePointer<_>”类型的值没有成员“baseAddress”。
如果我明确指定 resultType 和 kPtr:
var k = Data(count: crypto_generichash_keybytes())
k.withUnsafeMutableBytes { (kPtr: UnsafeMutableRawBufferPointer) -> Void in
flutter_sodium.crypto_generichash_keygen(kPtr.baseAddress)
}
我反而得到了
UnsafeMutableRawBufferPointer' 不能转换为 'UnsafeMutablePointer<_>'。
有没有快速的专家可以帮助我找出正确的方法来做到这一点?我知道警告只是警告,但我更喜欢编译时没有警告的代码。
在发布此问题之前,我查看了Swift 5.0: 'withUnsafeBytes' is deprecated: use `withUnsafeBytes<R>(...),这对我的情况没有帮助,因为我没有加载指针而是使用数据。另外,我已经完全按照文档告诉我的去做了,但这仍然没有帮助。
编辑:为了更清楚一点,350 多个警告中的一些与代码中分配了 Data 的代码有关,但是其中一些是我从外部来源收到 Data 的地方。看起来像这样:
let args = call.arguments as! NSDictionary
let server_pk = (args["server_pk"] as! FlutterStandardTypedData).data
let server_sk = (args["server_sk"] as! FlutterStandardTypedData).data
let client_pk = (args["client_pk"] as! FlutterStandardTypedData).data
var rx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
var tx = Data(count: flutter_sodium.crypto_kx_sessionkeybytes())
let ret = rx.withUnsafeMutableBytes { rxPtr in
tx.withUnsafeMutableBytes { txPtr in
server_pk.withUnsafeBytes { server_pkPtr in
server_sk.withUnsafeBytes { server_skPtr in
client_pk.withUnsafeBytes { client_pkPtr in
flutter_sodium.crypto_kx_server_session_keys(rxPtr, txPtr, server_pkPtr, server_skPtr, client_pkPtr)
}
}
}
}
}
用对应的方法调用
SODIUM_EXPORT
int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
unsigned char tx[crypto_kx_SESSIONKEYBYTES],
const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
__attribute__ ((warn_unused_result));
(而且我知道代码并不是真正的最佳 swift,但是在处理 dart 和 swift 之间的互操作性时,这是 Flutter 团队提出的如何做到这一点)。
当我提出这个问题时,我试图将其提炼为最简单的情况,但该情况的具体答案与我遇到的整体问题不同。
【问题讨论】:
-
很高兴您在 Swift 5 刚刚发布时提出了这个问题。让我更轻松地过渡。
-
这是我修复它的方法:stackoverflow.com/a/58008707/1151916
标签: swift