首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从闭包委托给另一个初始化器

从闭包委托给另一个初始化器
EN

Stack Overflow用户
提问于 2017-09-28 06:04:06
回答 1查看 111关注 0票数 2

我正在研究如何从DispatchData实例中创建一个Data实例。我从一个静态函数开始:

代码语言:javascript
复制
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)
    }
}

这很好(巧合的是,它与这个答案非常相似)。然后,我决定在扩展中将其作为初始化器添加到DispatchData中,并写道:

代码语言:javascript
复制
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的行上犹豫不决。

初始化前由闭包捕获的变量“self.__wrapped”

这是有意义的--编译器不希望在我将self委托给init(bytes: UnsafeRawBufferPointer)之前捕获它,因为存储的变量(在本例中是__wrapped )还没有初始化。但是我找不到获得UnsafeRawBufferPointer的另一种方法;我不能从data.withUnsafeBytes返回它,按照文档

警告 字节指针参数不应在调用闭包的生存期之外存储和使用。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-28 10:09:50

扩展的问题是,尽管编译器知道将闭包作为非转义参数传递给withUnsafeBytes(_:);但它无法保证只调用一次(初始化所需的)。

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

代码语言:javascript
复制
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?时,有一个从call到UnsafeRawPointer?的隐式转换;因此,我们不需要将它封装在初始化调用中。

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

代码语言:javascript
复制
private extension DispatchData {
  init(data: Data) {
    self = data.withUnsafeBytes(DispatchData.init)
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46462022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档