现在使用Swift,一些函数标有throws
,这迫使开发人员在do - try catch
块内调用该函数。
但是开发人员如何知道该函数抛出的不同异常列表?
作为参考,这是一行Java代码:
static void employeeAge(int age) throws MyExceptionA,MyExceptionB
很明显,例外情况是2 MyExceptionA
和MyExceptionB
,开发人员可以决定采取不同的行动,具体取决于错误。
我们可以在Swift上实现相同的目标吗?
答案 0 :(得分:4)
当Swift文档说明函数throws
时,它们意味着抛出ErrorType
(在Cocoa API中通常为NSError
),而不是例外。
考虑do-try-catch
createDirectoryAtPath
的以下NSFileManager
流程:
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
do {
try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: false, attributes: nil)
} catch {
// 'error' variable automatically populated
print(error)
print(error.dynamicType)
}
createDirectoryAtPath
将失败,因为文档目录已存在。记录dynamicType
的{{1}}表示它实际上是error
个对象:
NSError
为了查看函数Error Domain=NSCocoaErrorDomain Code=516 "The file “Documents” couldn’t be saved in the folder “35B0B3BF-D502-4BA0-A991-D07568AB87C6” because a file with the same name already exists." UserInfo={NSFilePath=/Users/jal/Library/Developer/CoreSimulator/Devices/E8A35774-C9B7-42F0-93F1-8103FBBC7118/data/Containers/Data/Application/35B0B3BF-D502-4BA0-A991-D07568AB87C6/Documents, NSUnderlyingError=0x7fa88bd14410 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}
NSError
的不同类型的错误,您必须检查throw
以获取信息,以确定抛出的错误类型以及如何处理每个错误。在error
的情况下,这将是其域,代码和描述。
在这种特殊情况下,该路径上已存在目录,因此文件管理器无法创建新目录。此操作可能失败的另一个原因的示例是文件管理器没有写访问权限。那将是错误代码256。
答案 1 :(得分:1)
我和OP有完全相同的问题。因为没有人真正回答这个问题(我也是这样),这是我的贡献。
在Swift 3和Xcode 8.3.3中,您将按如下方式处理个别异常。下面我将以FileManager为例给出一个例子。
首先,您将只有一个catch块来捕获该方法抛出的任何错误。然后,您将该错误转换为NSError。与Swift中的Error协议相反,NSError是一个REAL错误类。然后,您可以在switch语句中提取该错误的代码。您必须知道该方法引发错误的域,然后在相应的头文件中找到错误代码。
在下面的示例中,NSCocoaErrorDomain中引发了与文件相关的错误,并且这些错误代码在Foundation / FoundationErrors.h中定义/列出。在我的电脑中,它们位于
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/FoundationErrors.h
用于macOS应用程序和
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/
适用于iPhone应用。
所以这是一个例子:
let home = FileManager.default.homeDirectoryForCurrentUser
let file = home.appendingPathComponent("file")
do {
let loadedString = try String(contentsOf: file)
}
catch {
let realError = error as NSError // As weird as it looks, Xcode actually wants this forced conversion
print(realError.localizedDescription)
switch realError.code {
case 257: // No permission
handleNoPermission()
case 260: // File not found
handleFileNotFound()
default:
handleUndefinedError()
}
}
.localizedDescription
在您的用户的语言中包含有关该错误的用户友好消息。如果在上面找不到文件,则以英文打印:The file “file” couldn’t be opened because there is no such file.
。它可以直接在您向用户显示的错误对话框中使用。
您还可以在此处找到有关每个域引发的错误的更多信息:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html
答案 2 :(得分:-2)
您在catch之后编写一个模式,以指示该子句可以处理的错误。
do {
try expression
statements
} catch pattern 1 {
statements
} catch pattern 2 where condition {
statements
}
请参阅使用Swift Programming Language的Do-Catch处理错误