gpt4 book ai didi

swift - 从闭包委托(delegate)给另一个初始化器

转载 作者:可可西里 更新时间:2023-11-01 00:56:27 25 4
gpt4 key购买 nike

我正在寻找从 Data 实例中创建 DispatchData 实例的方法。我从一个静态函数开始:

static func dispatchData(fromData data: Data) -> DispatchData {
return data.withUnsafeBytes { (typedPtr: UnsafePointer<UInt8>) -> DispatchData in
let bufferPtr = UnsafeRawBufferPointer(start: UnsafeRawPointer(typedPtr), count: data.count)
return DispatchData(bytes: bufferPtr)
}
}

这很好用(巧合的是与 this answer 非常相似)。然后我决定在扩展中将它作为初始化程序添加到 DispatchData 并写道:

private extension DispatchData {
init(data: Data) {
data.withUnsafeBytes { (typedPtr: UnsafePointer<UInt8>) in // 1
let bufferPtr = UnsafeRawBufferPointer(start: UnsafeRawPointer(typedPtr), count: data.count)
self.init(bytes: bufferPtr)
}
}
}

此时,编译器在标记为 //1 的行上犹豫不决:

Variable 'self.__wrapped' captured by a closure before being initialized

这是有道理的——编译器不希望在我委托(delegate)给init(bytes: UnsafeRawBufferPointer)之前捕获self,因为存储的变量——比如__wrapped,在这种情况下——还没有初始化。但是我看不到另一种获取 UnsafeRawBufferPointer 的方法;根据 documentation,我无法从 data.withUnsafeBytes 返回它:

Warning

The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.

我知道我可以回到使用静态函数来实现我想要的,但如果有一种方法可以添加这个初始化程序,我会更喜欢它。有没有办法让这个初始化器按预期工作?

最佳答案

您的扩展的问题在于,尽管编译器知道您将闭包作为非转义参数传递给 withUnsafeBytes(_:) ;它不能保证它将被调用一次并且一次(这是初始化所必需的)。

一个简单的解决方案是,与其链接到另一个初始化器,不如构造一个新的 DispatchData 实例。自己,然后将其分配给 self , 从而完成初始化:

import Foundation

private extension DispatchData {
init(data: Data) {
self = data.withUnsafeBytes { (typedPtr: UnsafePointer<UInt8>) in
DispatchData(bytes:
UnsafeRawBufferPointer(start: typedPtr, count: data.count)
)
}
}
}

另请注意,有一个从 UnsafePointer<UInt8> 的隐式转换至 UnsafeRawPointer?将其作为参数传递时;所以我们不需要将它包装在初始化程序调用中。

在 Swift 5 中,withUnsafeBytes给你一个 UnsafeRawBufferPointer直接:

private extension DispatchData {
init(data: Data) {
self = data.withUnsafeBytes(DispatchData.init)
}
}

关于swift - 从闭包委托(delegate)给另一个初始化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46462022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com