我有一个巨大的代码库,我想打破错误"致命错误:在解开可选值时意外发现nil"
最好的方法是什么?
我尝试添加两者:(在断点子窗口中)
- "添加快速错误断点"
- "添加异常断点"
但这并没有做到。这是否意味着 nil 在某些框架代码中而不是我的代码中?
解包选项由编译器转换为对 _getOptionalValue() 的调用,() 在 nil
值的情况下调用_preconditionFailure()
,这将转换为对 _fatalErrorMessage()
的调用。
所以你需要为_fatalErrorMessage
设置断点。这里的诀窍是您需要为函数的损坏名称设置断点,即 _TTSf4s_s_d_d___TFSs18_fatalErrorMessageFTVSs12StaticStringS_S_Su_T_
。
如果为此添加符号断点,则每次发生致命错误时都会命中断点。这意味着您将捕获所有nil
解包,但是您还将捕获触发致命错误的其他一些代码段。您应该能够在函数的参数上设置一些条件,以便仅在传递unexpectedly found nil while unwrapping an Optional value
时才命中断点,但是我个人没有玩过lldb
的这个功能,所以我不确定您需要如何在断点编辑器中设置此条件。
更新。在 Swift 3(Xcode 8 beta 6)中,应将断点设置为_TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
下面介绍了如何找出任何 Swift 版本的函数名称,以便将断点设置为:
- 查找您的构建应用程序位置(可以在 Xcode 导航器 -> 产品 ->您的应用程序 Name.app 中轻松找到)
-
列出嵌入在应用程序捆绑包中的
libswiftCore.dylib
的所有全局符号,grep byfatalError
。因此,例如,如果您的构建应用程序处于/Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app/
,您应该运行nm -g /Users/your.username/Library/Developer/Xcode/DerivedData/YourApp-randomchars/Build/Products/Debug-iphonesimulator/YourApp.app//Frameworks/libswiftCore.dylib | grep fatalError
-
检查输出并获取损坏的方法名称。如果函数重载,则可能有多个符号。示例输出如下所示:
0000000000032f50 T __TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never 00000000001663b0 T __TTSfq4n_n_d_d_n___TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su5flagsVs6UInt32_Os5Never
-
确保在添加断点之前删除前导下划线,该断点来自 C 名称重整(因此对于上述输出,您应该只保留两个符号的一个前导下划线)。
- 添加断点并强制解开 nil 值的包装,以确保它们正常工作。
快乐的零展开狩猎:)