调用抛出并尝试转换返回值的函数,如果失败则静默中止

Call function that throws and attempt to cast the returned value, abort silently if either fails

我正在 guard 调用可能抛出的方法(CoreData 获取请求),同时我将返回值转换为特定类型的数组:

guard let results = try? managedContext.executeFetchRequest(fetchRequest) as? [MyManagedObjectClass] else {

    // Bail out if fetch or cast fails:
    return
}

我的理解是,因为我使用的是 guard/try?/else(而不是 do/try/catch),上面的 else 块(即 return 语句)如果发生以下任一情况,将被执行:

  1. 提取请求失败(和 throws)
  2. 提取请求成功,但将返回值转换为 [MyManagedObjectClass] 失败。

上面的代码有效,但是 after 控件成功通过了 guard 检查,变量 results 最终成为类型 [MyManagedObjectClass]? ("可选数组 MyManagedObjectClass").

因此,如果我想 -say- 遍历数组元素 我必须先解包它:

if let results = results {
    // now, 'results' is of type:
    // "(non-optional) Array of MyManagedObjectClass" 

    for element in results {
        // (process each element...)
    }
}

可以guard语句之后进行转换时使用as!而不是as?;这使得 results 成为一个非可选数组。

但是,如果获取成功但转换失败,它仍然会触发运行时错误(崩溃)而不是控制流到 else 块,对吗?

有没有更聪明的方法?(捕获两个错误,最后得到一个非可选数组)


注意:我知道将失败原因(获取和转换)集中到一个 else 块中并不是最好的设计,也许我应该检查一下两者分开(也许我应该使用更传统的do/try/catch),但我想更好地掌握这个复杂结构的细节。

您需要将 try 调用括在括号中:

let results = (try? managedContext.executeFetchRequest(fetchRequest)) as? [MyManagedObjectClass]

否则 try? 将应用于整个表达式,生成一个可选值并分配给 results