Swift 3.1 中的数据字节到 sockaddr 的转换

Posted

技术标签:

【中文标题】Swift 3.1 中的数据字节到 sockaddr 的转换【英文标题】:Data bytes to sockaddr conversion in Swift 3.1 【发布时间】:2017-07-19 10:08:38 【问题描述】:

我将Data bytes 转换为sockaddr 以获得sa_family_t

ObjC,如下:

NSData *     hostAddress;
- (sa_family_t)hostAddressFamily 
    sa_family_t     result;

    result = AF_UNSPEC;
    if ( (self.hostAddress != nil) && (self.hostAddress.length >= sizeof(struct sockaddr)) ) 
        result = ((const struct sockaddr *) self.hostAddress.bytes)->sa_family;
    
    return result;

我正在尝试将其转换如下:

var hostAddress:Data?

 private func hostAddressFamily() -> sa_family_t

        var result: sa_family_t = sa_family_t(AF_UNSPEC)
        if (hostAddress != nil) && ((hostAddress?.count ?? 0) >= MemoryLayout<sockaddr>.size) 

            // Generic parameter 'ContentType' could not be inferred
            self.hostAddress!.withUnsafeBytes( bytes in
                bytes.withMemoryRebound(to: sockaddr.self, capacity: 1, sockBytes in
                    result = sockBytes.pointee.sa_family
                )
            )
        

        return result
    

Getting error : Generic parameter ‘ContentType’ could not be inferred

【问题讨论】:

【参考方案1】:

Data.withUnsafeBytesType的签名:

func withUnsafeBytes<ResultType, ContentType>(_ body: (Swift.UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType

此方法对ResultTypeContentType 是通用的,ContentType 用于闭包体的参数中。

编译器想说的是它不知道bytes 是什么类型。通常,要修复此类错误,您需要在闭包中注释类型:

data.withUnsafeBytes  (_ bytes: UnsafePointer<...>) -> Void in ... 

此外,由于NSData 是无类型的,并且您已经指定了将其绑定到的类型,因此您不太可能需要绑定内存两次。


把它们放在一起:

func hostAddressFamily() -> sa_family_t 

  var result = sa_family_t(AF_UNSPEC)

  guard
    let hostAddress = hostAddress,
    hostAddress.count >= MemoryLayout<sockaddr>.size
  else 
    return result
  

  hostAddress.withUnsafeBytes  (_ bytes: UnsafePointer<sockaddr>) in
    result = bytes.pointee.sa_family
  

  return result

【讨论】:

以上是关于Swift 3.1 中的数据字节到 sockaddr 的转换的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Swift 3.1 中的 API 创建解析数据,API 以括号开头和结尾

Swift 3.1 的一些新特性

SWIFT:将字节从 NSData 粘贴到 Struct?

Swift 3.1 中的 CocoaTouch 类

Swift 2.3 到 Swift 3.1 迁移 - Alamofire 请求错误

从 swift 2.3 问题迁移到 swift 3.1