swift2 在swift 2.0中将NSData转换为!CFDataRef

uqcuzwp8  于 2022-11-06  发布在  Swift
关注(0)|答案(3)|浏览(274)

我在一个代码中有一行被弃用,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)
yqkkidmi

yqkkidmi1#

一个稍微安全的版本:

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这样的技术。这使您的代码在多核电脑上立即发挥优势,而不需要您做很多工作。
来自文件系统编程指南

w80xi6nr

w80xi6nr2#

但是,在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
dy2hfwbg

dy2hfwbg3#

@Abizern的答案是有效的,但是用CFDataCreateWithBytesNoCopy代替CFDataCreate更有效。

相关问题