Swift 2: 无法使用定义调用 createDirectoryAtUrl

Swift 2: Can't call createDirectoryAtUrl with definition

我目前正在使用 Swift 2 在 xCode7 beta 2 上开发一个应用程序(目前这是一项要求)。

这是我要调用的内容:

let fileManager = NSFileManager.defaultManager()
let tempDirectoryURL = NSURL(string: NSTemporaryDirectory())!
let directoryURL = tempDirectoryURL.URLByAppendingPathComponent("com.test.manager/multipart.form.data")
var error: NSError?

if fileManager.createDirectoryAtURL(directoryURL, createIntermediates: true, attributes: nil) {
 ...
}

这是我收到的错误:

Cannot invoke 'createDirectoryAtURL' with an argument list of type '(NSURL, createIntermediates: Bool, attributes: nil)'

这令人困惑,因为当我右键单击 "view definition" 时得到的 createDirectoryAtURL 的定义是:

 func createDirectoryAtURL(
    url: NSURL, 
    withIntermediateDirectories createIntermediates: Bool, 
    attributes: [String : AnyObject]?
 ) throws

唯一不逐字匹配的参数是最后一个参数 "attributes",文档(和所有示例用法)明确指出可以接受值 nil。

Apple's Documentation:

If you specify nil for this parameter, the directory is created according to the umask(2) Mac OS X Developer Tools Manual Page of the process.

这里有两个问题:

  1. 您已为其内部名称切换了参数标签。第二个参数的标签——函数名的一部分,调用它需要——是 withIntermediateDirectories。该函数的实现者将该参数的值称为 createIntermediates。所以你的电话应该是这样的:

    fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
    
  2. 注意你引用的签名:

    func createDirectoryAtURL( ... ) throws
    

    您将此调用用作 if 语句的条件 — 这意味着您需要一个 returns Bool 的函数。编译器试图通过寻找类型签名为 (NSURL, Bool, [String : AnyObject]?) -> Bool 的名为 createDirectoryAtURL 的函数来满足 if 语句的要求,并抱怨因为它只看到签名为 [=21] 的函数=].

Swift 2 中的错误处理系统采用 return BOOL 并具有 NSError out 参数的 ObjC 方法,并将它们转换为 throwing没有 return 类型的方法(即它们 return Void)。因此,如果您正在查看使用此类方法的 Swift 1.x 代码或移植 ObjC 代码,则需要更改如下模式:

var error: NSError? 
if fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil, error: &error) {
    // all good
} else {
    // handle error
}

并改用这样的模式:

do {
    try fileManager.createDirectoryAtURL(directoryURL, withIntermediateDirectories: true, attributes: nil)
    // if here, all is good
} catch {
    // handle error
}