Swift 捕获运行时异常

Posted

技术标签:

【中文标题】Swift 捕获运行时异常【英文标题】:Swift Catch Runtime Exceptions 【发布时间】:2017-03-23 10:41:07 【问题描述】:

我正在对应用程序运行模糊测试,因此我专门寻找未处理的运行时错误。该应用程序是用 ObjC 和 Swift 编写的,但单元测试是用 Swift 编写的。

我理解 swift 的基础不是捕捉任意运行时异常,但这纯粹是为了单元测试。如何捕获运行时这些异常(即索引超出范围等)

【问题讨论】:

我们谈论的是 Obj-C 异常还是 Swift 异常? Swift 异常不容易处理。使用实用程序 Obj-C 函数可以简单地捕获 Obj-C 异常。 我认为大部分错误都来自于 ObjC——解决这些问题就足够了! Catching NSException in Swift的可能重复 【参考方案1】:

为了在 Swift 中捕获 Obj-C 异常,我使用了一个简单的 Obj-C 类:

#import "ObjC2Swift.h"

@implementation ObjC

+ (id)catchException:(id(^)())tryBlock error:(__autoreleasing NSError **)error 
    @try 
        id result = tryBlock();
        return result;
    
    @catch (NSException *exception) 
        if (error) 
            *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:exception.userInfo];
        
        return nil;
    


@end

在 Swift 中称为

let result = try? ObjC.catchException  ... dangerous code here ... 

对于不返回任何内容的块,您可能需要不同的变体。

不要被滥用。 Obj-C 异常是邪恶的,我使用它只是因为我需要一个使用它们的库。

【讨论】:

好主意,点赞。我做了一些小的改进: 1) 将异常作为 catchException() 的返回值返回给 Swift,以便它可以检查异常类或任何属性,如原因,包括 NSException 子类中的自定义属性。不要将其转换为 NSError。 2) 捕获 id,以防有人抛出不是从 NSException 派生的异常。 @VaddadiKartick 如果你想使用 Swift try 你不应该返回异常并且你需要 NSError 转换:) NSError 在 Obj-C 中处理,Swift @987654326 @ 是基于假设您在出现错误时返回nil(或false)。 我了解您的偏好。我只是想说我不介意将异常作为返回值,并且我希望将 Objective-C 中可用的所有信息传递回 Swift。 我尝试了你的解决方案,但我得到'Type "ObjC' has no member 'catchException" 我使用 header-bridge-file 在那里添加 objC 实现,这是错的吗?任何想法我做错了什么?谢谢 @Zich 你需要一个头文件,上面有方法声明和实现文件。然后从桥接头导入头文件。

以上是关于Swift 捕获运行时异常的主要内容,如果未能解决你的问题,请参考以下文章

swift - 异常处理

swift - 如何处理未捕获的异常

是否可以捕获除运行时异常之外的所有异常?

异常抛出与捕获的思考

由于运行应用程序时未捕获的异常而终止应用程序

Swift 2 到 3 迁移错误(libc++abi.dylib:以 NSException 类型的未捕获异常终止)