没有捕获异常

时间:2019-06-27 20:02:42

标签: ios swift nsattributedstring nsmutableattributedstring

Crashlytics报告以下行是有时抛出NSInternalInconsistencyException

let attrStr = try NSMutableAttributedString(
        data: modifiedFont.data(using: String.Encoding.unicode, 
        allowLossyConversion: true)!,
        options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue],
        documentAttributes: nil)

在这里,我对为什么发生这种情况(there's a 3 year old question about it)的兴趣不如我在捕获/处理此异常时的兴趣。我试图这样做:

do {
    let attrStr = try NSMutableAttributedString(
       data: modifiedFont.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
       options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue],
       documentAttributes: nil)

     self.attributedText = attrStr
} catch {
    self.attributedText = nil
    self.text = text.stripHTML()
}

...但是由于某些原因,此方法不起作用-仍在报告异常。

我要以正确的方式捕捉它吗?可以完全抓住吗?如果没有,我有什么选择?

3 个答案:

答案 0 :(得分:2)

Swift将具有可为空的返回值和尾随NSError**参数的Objective-C方法转换为引发Swift的方法。但是,在Objective-C中,您也可以引发异常。这些与NSError不同,Swift不会捕获它们。实际上,没有办法在Swift中抓住它们。您必须编写一个Objective-C包装器,以捕获异常并将其以Swift可以处理的某种方式传递回去。

您可以在Apple文档Handling Cocoa Errors in Swift“仅在Objective-C中处理异常”部分中找到它。

因此,您证明 可以捕获它,但是值得考虑是否应该这样做(请参阅下面@Sulthan的评论)。据我所知,大多数Apple框架都不安全(请参见Exceptions and the Cocoa Frameworks),因此您不能只是捕获异常并继续进行,就好像什么都没发生一样。最好的选择是保存您所能做的,并尽快退出。要考虑的另一个问题是,除非您抛出异常,否则Crashlytics之类的框架不会将异常报告给您。因此,如果您确实决定要捕获它,则应该对其进行记录和/或重新抛出,以使您知道它正在发生。

答案 1 :(得分:0)

NSInternalInconsistencyException是一个Objective-C异常,Swift代码无法捕获。您只能使用Objective-C代码捕获这种类型的异常,因此您将需要创建一个Objective-C包装器以从Swift代码中捕获该异常,例如,使用以下Objective-C方法:

+ (NSException *)tryCatchWithBlock:(void (^)(void))block {
    @try {
        block();
    } @catch (NSException *exception) {
        return exception;
    } @catch (id exception) {
        return [NSException exceptionWithName:NSGenericException reason:nil userInfo:nil];
    }
    return nil;
}

此方法是我的库中名为LSCategories:https://github.com/leszek-s/LSCategories的一部分,具有各种有用的类别/扩展名,因此您也可以轻松地将此库与CocoaPods集成到您的Swift项目中,然后可以通过包装快速代码来捕获NSInternalInconsistencyException像这样:

let objcException = NSException.lsTryCatch {
    // put your swift code here
}

因此,如果要执行此操作,便可以捕获该异常。但更重要的是,您应该调查您的情况为何会发生此异常。也许您是在后台线程上调用代码。

答案 2 :(得分:-1)

我想当您尝试将modifiedFont转换为Data时会发生崩溃。
modifiedFont.data(using: String.Encoding.unicode, allowLossyConversion: true)! 如果将数据转换行移出try-catch范围,则很可能会遇到相同的错误。为了避免崩溃,请不要使用强制解包(!)。

如果在初始化NSMutableAttributedString期间抛出任何错误,则会被捕获。