2017-04-13 74 views
1

我想将我的nsData解码为字符串数组。我现在有这样的代码:将nsData解码为字符串数组

func nsDataToStringArray(data: NSData) -> [String] { 
      var decodedStrings = [String]() 

      var stringTerminatorPositions = [Int]() 

      var currentPosition = 0 
      data.enumerateBytes() { 
       buffer, range, stop in 

       let bytes = UnsafePointer<UInt8>(buffer) 
       for i in 0 ..< range.length { 
        if bytes[i] == 0 { 
         stringTerminatorPositions.append(currentPosition) 
        } 

        currentPosition += 1 
       } 
      } 

      var stringStartPosition = 0 
      for stringTerminatorPosition in stringTerminatorPositions { 
       let encodedString = data.subdata(with: NSMakeRange(stringStartPosition, stringTerminatorPosition - stringStartPosition)) 
       let decodedString = NSString(data: encodedString, encoding: String.Encoding.utf8.rawValue)! as String 
       decodedStrings.append(decodedString) 
       stringStartPosition = stringTerminatorPosition + 1 
      } 

      return decodedStrings 
     } 

但我得到这一行的错误:让字节= UnsafePointer<UInt8>(buffer)

不能调用类型“UnsafePointer”初始化与类型的 参数列表“( UnsafeRawPointer)'

我是否需要将缓冲区转换为UnsafePointer?如果是这样,我该怎么做?

回答

2

enumerateBytes()关闭bufferUnsafeRawPointer ,你必须在斯威夫特3“重新绑定”它的UInt8指针:

// let bytes = UnsafePointer<UInt8>(buffer) 
let bytes = buffer.assumingMemoryBound(to: UInt8.self) 

但为什么这么复杂?您可以使用

func nsDataToStringArray(nsData: NSData) -> [String] { 
    let data = nsData as Data 
    return data.split(separator: 0).flatMap { String(bytes: $0, encoding: .utf8) } 
} 

这是如何工作的?

  • DataUInt8一个Sequence,因此
  • split(separator: 0)可以在其上被调用,返回的 “数据切片”(这是视图到源数据,而不是拷贝)的阵列。
  • 每个“数据片”又是SequenceUInt8,从中可以用String(bytes: $0, encoding: .utf8)创建 String。 这是一个failable初始值设定项(因为数据可能是无效的UTF-8)。
  • flatMap { ... }返回一个数组,其中包含所有非零结果,即 ,即包含所有字符串的数组,该数组可以从零个字节之间的有效UTF-8代码序列创建为 。
+0

在斯威夫特3我宁愿签名'FUNC字符串数组(从NSData的:NSData的)';-) – vadian

+0

@vadian:的确!如果可能的话,或者'func stringArray(来自data:Data)'。 - 我保留这个名字,以便OP可以用他/她的代码直接测试它。 –

+0

我们不需要讨论在Swift 3中滥用过时的'NS ...'基础类...... – vadian