NSError.setUserInfoValueProvider 无限循环

Posted

技术标签:

【中文标题】NSError.setUserInfoValueProvider 无限循环【英文标题】:NSError.setUserInfoValueProvider infinite loop 【发布时间】:2018-10-30 15:05:54 【问题描述】:

NSError.setUserInfoValueProvider(forDomain:provider:) 是在 MacOS 10.11/ios 9 中引入的,作为使用块为给定错误域填充 userInfo 字典的一种方式,从而避免大量样板代码和代码重复,这可能扔。

我尝试这样使用它:

if NSError.userInfoValueProvider(forDomain: "Test") == nil 
    NSError.setUserInfoValueProvider(forDomain: "Test") err, userInfoKey in
        print("This is an error:", err, userInfoKey)
        return nil
    

调用站点如下所示:

throw NSError(domain: "Test", code: 0, userInfo: nil)

当错误被抛出时,日志中会填满“这是一个错误:”,但错误本身或userInfoKey 永远不会被打印出来。程序最终中止并在日志中显示最后一条消息:

警告:无法执行支持代码来读取 Objective-C 类数据 进行中。这可能会降低类型信息的质量 可用。

【问题讨论】:

【参考方案1】:

问题是在

中打印err
print("This is an error:", err, userInfoKey)

递归调用相同的值提供程序,因为错误的字符串表示是确定的。然后程序最终因堆栈溢出而崩溃。您可以通过在该行设置断点来验证这一点。

如果您将行更改为

print("This is an error:", userInfoKey)

然后一切都按预期进行。

【讨论】:

确实是问题所在——NSError 会尽最大努力呈现一个好的字符串表示,在这个过程中遍历它的所有userInfo。当这种情况发生在应该提供相同 userInfo 值的块中时,会导致无限递归。

以上是关于NSError.setUserInfoValueProvider 无限循环的主要内容,如果未能解决你的问题,请参考以下文章