【问题标题】:Catch Objective-C exception in Swift在 Swift 中捕获 Objective-C 异常
【发布时间】:2016-05-09 06:06:56
【问题描述】:

我正在尝试使用 obj.setValue(value, forKey: key) 在我的 Swift 代码中设置 @objc 对象的值。

当对象具有正在设置的属性时,它可以正常工作。但如果不是这样,我的应用程序会因未捕获的NSException(“类不符合键值编码...”)而严重崩溃。

我怎样才能像在 Objective-C 中一样捕捉和吸收这个异常,以免我的应用程序崩溃?我尝试将它包装在 Swift try-catch 中,但它抱怨没有任何指令抛出并且什么都不做。

【问题讨论】:

  • 你真的需要KVC吗?字典中的对象应该使用setObject:forKey: 或键下标设置,尤其是在 Swift 中。
  • 是的,我正在编写一个 XML 解析器,需要能够通过对象的名称设置任意属性。
  • 那么,如果密钥存在,而不是捕获异常检查。
  • 完全可以。我不认为有办法做到这一点!

标签: swift exception-handling swift2 nsexception


【解决方案1】:

看到这个answer

//
//  ExceptionCatcher.h
//

#import <Foundation/Foundation.h>    

NS_INLINE NSException * _Nullable tryBlock(void(^_Nonnull tryBlock)(void)) {
    @try {
        tryBlock();
    }
    @catch (NSException *exception) {
        return exception;
    }
    return nil;
}

【讨论】:

  • 成功了!不漂亮,但我很高兴这至少是可能的!
【解决方案2】:

不幸的是,这不是我希望的答案:

虽然 Swift 错误处理类似于 Objective-C 中的异常处理,但它是完全独立的功能。如果 Objective-C 方法在运行时抛出异常,Swift 会触发运行时错误。没有办法直接在 Swift 中从 Objective-C 异常中恢复。任何异常处理行为都必须在 Swift 使用的 Objective-C 代码中实现。

摘自:Apple Inc.“将 Swift 与 Cocoa 和 Objective-C 结合使用 (Swift 2.1)。”电子书。 https://itun.es/ca/1u3-0.l

我的下一个攻击计划是添加一个我可以调用的 Objective-C 函数,它将尝试包装在 @try/@catch 中。这真的很糟糕,Apple。

【讨论】:

    【解决方案3】:

    带有实用程序错误类型的 Swift 5 版本:

    NS_INLINE NSException * _Nullable ExecuteWithObjCExceptionHandling(void(NS_NOESCAPE^_Nonnull tryBlock)(void)) {
        @try {
            tryBlock();
        }
        @catch (NSException *exception) {
            return exception;
        }
        return nil;
    }
    
    public struct NSExceptionError: Swift.Error {
    
       public let exception: NSException
    
       public init(exception: NSException) {
          self.exception = exception
       }
    }
    
    public struct ObjC {
    
       public static func perform(workItem: () -> Void) throws {
          let exception = ExecuteWithObjCExceptionHandling {
             workItem()
          }
          if let exception = exception {
             throw NSExceptionError(exception: exception)
          }
       }
    }
    
    

    【讨论】:

      【解决方案4】:

      我想说出这个问题中给出的答案:

      Catching NSException in Swift

      由于您仍然可以以自然的方式在调用中使用 Swift 的 do/catch,因此 Swift 的下一个最好的事情是实际捕获 ObjC 异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-15
        • 2015-09-20
        • 2016-06-26
        • 2011-04-26
        • 2011-07-23
        • 2010-11-15
        • 1970-01-01
        • 2013-12-02
        相关资源
        最近更新 更多