【问题标题】:Cast NSData as! CFDataRef in swift 2.0将 NSData 转换为! swift 2.0 中的 CFDataRef
【发布时间】:2015-10-01 08:50:55
【问题描述】:

我的代码中有一行已被弃用,XCode 中有建议用什么替换它,但我无法理解其中的区别,这是我的三行有效:

let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData.dataWithContentsOfMappedFile(path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef

现在根据警告和建议,我将代码更改为:

let path = NSBundle.mainBundle().pathForResource("example", ofType: ".p12")
let pkcs12Data = NSData(contentsOfFile: path!)
let cf: CFDataRef = pkcs12Data as! CFDataRef

这给了我一个错误:

EXC_BAD_INSTRUCTION (CODE=EXC_I386_INVOP SUBCODE=0x0)

【问题讨论】:

  • 不要投射,使用CFDataCreate()
  • 我正在尝试,我必须说我正在学习 swift 并使用它第 8 天,我正在努力将方法所需的所有参数放在一起。 CFDataCreate(_ allocator: CFAllocator!, _ bytes: UnsafePointer, _ length: CFIndex) 相当混乱...
  • CFDataCreate(NULL, pkcs12Data.bytes, pkcs12Data.length)?
  • 嗯,我明白你为什么自然会期望它起作用。但是它会引发另一个错误:/Users/user/code/xyz/CryptoOperations/CryptographyOperations/IdentityFileReader.swift:30:42: Cannot convert value of type '()' to expected argument type 'CFAllocator!'
  • 然后第二个参数还有一个:/Users/user/code/xyz/CryptoOperations/CryptographyOperations/IdentityFileReader.swift:30:66: Cannot convert value of type 'UnsafePointer<Void>' (aka 'UnsafePointer<()>') to expected argument type 'UnsafePointer<UInt8>'

标签: ios casting swift2 nsdata cfdata


【解决方案1】:

稍微安全一点的版本:

guard
    let url = NSBundle.mainBundle().URLForResource("example", withExtension: ".p12"),
    let data = NSData(contentsOfURL: url)
    else { // Do something because you couldn't get the file or convert it to NSData }

    let dataPtr = CFDataCreate(kCFAllocatorDefault, UnsafePointer<UInt8>(data.bytes), data.length)

注意,使用基于文件的 URL 而不是字符串路径。

在决定调用哪些例程时,请选择允许您使用 NSURL 对象指定路径的例程,而不是使用字符串指定路径的例程。大多数基于 URL 的例程是在 OS X v10.6 及更高版本中引入的,并且从一开始就被设计为利用 Grand Central Dispatch 等技术。这使您的代码在多核计算机上具有立竿见影的优势,同时不需要您做很多工作。

来自File System Programming Guide

【讨论】:

    【解决方案2】:

    然而,在 Swift 4 中,你应该这样做:

    Xcode 9.2 似乎自动将 NSData 视为 Data 当两个选项放在同一个 guard-let 子句中时。 我必须将这两个选项放在单独的 guard-let 子句中,如下所示:

    //        guard let url = Bundle.main.url(forResource: "example", withExtension: ".p12"),
    //            let data = NSData(contentsOf: url) else {
    //            return
    //        }
    
    guard let url = Bundle.main.url(forResource: "example", withExtension: ".p12") else {
        return
    }
    guard let data = NSData(contentsOf: url) else {
        return
    }
    let bytes = data.bytes.assumingMemoryBound(to: UInt8.self)
    let cfData = CFDataCreate(kCFAllocatorDefault, bytes, data.length) // CFData object you want
    

    【讨论】:

      【解决方案3】:

      @Abizern 的回答是有效的,但是使用CFDataCreateWithBytesNoCopy 而不是CFDataCreate 更有效。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-06
        • 1970-01-01
        • 1970-01-01
        • 2014-12-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-24
        相关资源
        最近更新 更多