Sup*_*tar 5 runtime-error objective-c swift
我正在从 Swift 调用一些旧的 Objective-C 代码,它经常会抛出这个错误,即使看起来没有出错:
do {
try objCObject.someMethod()
}
catch {
print(error)
// Trying to handle the error here
}
Run Code Online (Sandbox Code Playgroud)
该方法的 Objective-C 签名如下所示:
- (BOOL) someMethodWithError: (NSError **) outError;
Run Code Online (Sandbox Code Playgroud)
在内部放置一个断点,catch我可以使用 LLDB 控制台看到这一点。
(lldb) po error
Foundation._GenericObjCError.nilError
(lldb) po error as NSError
Error Domain=Foundation._GenericObjCError Code=0 "(null)"
Run Code Online (Sandbox Code Playgroud)
这里发生了什么,我该如何处理?当我尝试在 Swift 中为此编写一个特殊案例时,我得到了这个:
/Path/To/My Code.swift:200:27: error: module 'Foundation' has no member named '_GenericObjCError'
catch Foundation._GenericObjCError.nilError {
^~~~~~~~~~ ~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这是当一个Objective-C的方法使用标准的可可方法错误引发所致:采取NSError **作为最后一个参数,并返回一个BOOL带有YES指示成功。如果这按预期工作,则仅NO在发生错误时返回值,然后相应地设置NSError **对象。
Swift 预计所有带有此签名的 Objective-C 方法都是这样工作的。
您所看到的是当这些方法之一由于某种原因行为不端并返回时NO未将NSError **参数设置为任何内容(或将其显式设置为nil)时会发生什么。
这可能是由于多种因素造成的,例如返回隐式转换为 的错误代码BOOL(因此,0成功代码被转换为NO失败代码),或者以不符合逻辑的方式编写返回行t 总是YES在成功时返回,或者因为实际上存在错误但作者不知道该设置为什么NSError **,等等。
至于处理这个,这是我会做的:
在这种情况下,我认为假设作者只是犯了一个错误并返回了错误的值是最安全的。最好完全忽略抛出的错误。
do {
try objCObject.someMethod()
}
catch {
let nsError = (error as NSError)
if nsError.code == 0,
nsError.domain == "Foundation._GenericObjCError" {
print("Got invalid error from Objective-C")
}
else {
// Actually handle your error here
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将其视为作者记录的错误。如果需要,您可以调整上面的示例代码以专门处理此错误。
这很简单。只需更改您的方法,使其仅NO在您处于真正的错误状态时才返回,并且始终确保NSError **如果调用方请求该对象已设置为有效的错误对象。
- (BOOL) someMethodWithError: (NSError **) outError {
[self.something attempt];
if (!self.something.succeeded) {
if (nil != outError) {
*outError = [self makeSomeDescriptiveErrorFromSomething: self.something];
}
return NO;
}
else {
return YES;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2128 次 |
| 最近记录: |