xcode 在 Swift 3 中将 NSData 转换为 NSString?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39619113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:18:36  来源:igfitidea点击:

Converting NSData to NSString in Swift 3?

xcodensstringnsdataswift3

提问by user2625833

I have a function that returns certain system values. It worked fine in Swift 2.2, and I just upgraded to Xcode 8 and Swift 3, and now it's failing.

我有一个返回某些系统值的函数。它在 Swift 2.2 中运行良好,我刚刚升级到 Xcode 8 和 Swift 3,现在它失败了。

func ioPlatExpertDevString(_ property: String) -> String {
    // Start tapping in to the IO Service
    let ioPlatformExpertDevice:io_service_t? = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))

    var sAnswer = "Not Found"
    let cfAnswer:AnyObject! = IORegistryEntryCreateCFProperty(ioPlatformExpertDevice!, "\(property)" as CFString!, kCFAllocatorDefault, 0).takeRetainedValue()
    if (cfAnswer != nil) {
        let nsAnswer = (cfAnswer as! NSString)
        sAnswer = nsAnswer.uppercased
    }

    // Close the IO Service
    IOObjectRelease(ioPlatformExpertDevice!)

    return sAnswer
}

Prior, I was using "CFData" instead of "AnyObject". It builds fine, but at runtime, I get the following error:

之前,我使用的是“CFData”而不是“AnyObject”。它构建良好,但在运行时,我收到以下错误:

Could not cast value of type '__NSCFData' (0x7fff7b833ec0) to 'NSString' (0x7fff7ac32038).

无法将“__NSCFData”(0x7fff7b833ec0)类型的值转换为“NSString”(0x7fff7ac32038)。

回答by Leo Valentim

Replace

代替

let nsAnswer = (cfAnswer as! NSString) 

To

let nsAnswer = NSString(data: cfAnswer as! Data, encoding: String.Encoding.utf8.rawValue)

回答by vadian

Please do notannotate types unless the compiler tell you to do.

请不要注释类型除非编译器告诉你这样做。

For example IOServiceGetMatchingServicereturns a non-optional io_service_t, your optional annotation makes it worse.

例如IOServiceGetMatchingService返回一个 non-optional io_service_t,你的可选注释会使情况变得更糟。

IORegistryEntryCreateCFPropertyreturns Unmanaged<CFTypeRef>!an annotation is not needed either as well as the string interpolation and the cast to implicit unwrapped optional.

IORegistryEntryCreateCFPropertyUnmanaged<CFTypeRef>!不需要返回注释,也不需要字符串插值和转换为隐式解包可选。

CFTypeRefcan be bridge casted to a native Swift type.

CFTypeRef可以桥接到原生 Swift 类型。

If the return type is (NS)Datait's most unlikely that it worked in prior versions.

如果返回类型是(NS)Data它在以前的版本中最不可能工作。

This code considers Stringand Dataif the latter can be converted to String.

此代码认为StringData如果后者可以转化为String

func ioPlatExpertDevString(_ property: String) -> String {
  // Start tapping in to the IO Service
  let ioPlatformExpertDevice = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))

  var sAnswer = "Not Found"
  let cfAnswer = IORegistryEntryCreateCFProperty(ioPlatformExpertDevice, property as CFString, kCFAllocatorDefault, 0).takeRetainedValue()
  if let cfData = cfAnswer as? Data, let answer = String(data:cfData, encoding:.utf8) {
    sAnswer = answer.uppercased()
  } else if let answer = cfAnswer as? String {
    sAnswer = answer.uppercased()
  }
  // Close the IO Service
  IOObjectRelease(ioPlatformExpertDevice)
  return sAnswer
}

回答by kakubei

For more recent versions of Swift:

对于更新的 Swift 版本:

String(decoding: data, as: UTF8.self)