在Swift中处理未捕获的异常valueForUndefinedKey

War*_*shi 5 error-handling runtime-error ios swift nsunknownkeyexception

我有一个第三方库类,其源代码不对我开放.例如这样:

class MyClass: NSObject {
    let myProperty = 10
} 
Run Code Online (Sandbox Code Playgroud)

我可以得到这样的myProperty价值.

let test = MyClass().value(forKey: "myProperty")  // 10
Run Code Online (Sandbox Code Playgroud)

我想检查是否myProperty存在MyClass.原因是如果第三方类实现将来发生变化,我不希望我的应用程序崩溃.

为了测试,我试过了

guard let test = MyClass().value(forKey: "myProperty1") else { return }  // crash
Run Code Online (Sandbox Code Playgroud)
if let test = MyClass().value(forKey: "myProperty1") { }  // crash
Run Code Online (Sandbox Code Playgroud)
do {
    let test = try MyClass().value(forKey: "myProperty1")  // crash
} catch { }
Run Code Online (Sandbox Code Playgroud)

在各方面我都崩溃了.

***由于未捕获的异常'NSUnknownKeyException'而终止应用程序,原因:'[<__ lldb_expr_80.MyClass 0x608000223a00> valueForUndefinedKey:]:此类不是密钥myProperty1的密码值编码.

Hej*_*azi 5

valueForKey:针对未定义的键调用 时,运行时会将调用转发valueForUndefinedKey:. 后者的默认实现只是引发NSUndefinedKeyException.

我们无法从 Swift 代码中捕获异常,但我们可以valueForUndefinedKey:在扩展中重写该方法并返回一些错误:

extension NSObject {
    @objc
    func value(forUndefinedKey key: String) -> Any {
        NSError(domain: "Dynamic", code: 404, userInfo: [NSLocalizedDescriptionKey: "Accessing undefined key: '\(key)'"])
    }
}
Run Code Online (Sandbox Code Playgroud)


Ham*_*ari 1

您必须通过与 lib dev 交谈来找到更好的解决方案

您可以使用Mirror reflection并检查其对象标签

let myClass = Mirror(reflecting: MyClass())
for (_, attr) in myClass.children.enumerated() {
  if let propertyName = attr.label, propertyName == "myProperty"{
   print(propertyName, attr.value)
  }
}
Run Code Online (Sandbox Code Playgroud)