如果您仔细查看 的签名fatalError
:
@noreturn public func fatalError(
@autoclosure message: () -> String = default,
file: StaticString = #file, line: UInt = #line)
您可以看到 the#file
和#line
default 参数。这些在编译时进行评估并解析为当前文件和行。
要不使用默认参数,您可以自己提供它们:
fatalError("Something went wrong", file: "", line: 0)
在发布配置上编译时,路径不包含在二进制文件中。
如果您#file
在标准库中搜索,您可以找到 4 个其他实例,其中两个已包含在发布版本中assert
,assertionFailure
其中不包含在发布版本中。其余 2 个是precondition
和preconditionFailure
。
解决方法
如果我们添加DEBUG
/RELEASE
符号:
我们可以对 mocked 等函数进行条件编译,这些函数在发布版本fatalError
中不使用预处理器语句:#file
#if RELEASE
@inline(__always) @noreturn func fatalError(@autoclosure message: () -> String = "") {
Swift.fatalError(message, file: "", line: 0)
}
@inline(__always) func preconditionAlt(@autoclosure condition: () -> Bool, @autoclosure _ message: () -> String = "") {
Swift.precondition(condition, message, file: "", line: 0)
}
@inline(__always) @noreturn func preconditionFailureAlt(@autoclosure message: () -> String = "") {
Swift.preconditionFailure(message, file: "", line: 0)
}
#else
@inline(__always) func preconditionAlt(@autoclosure condition: () -> Bool, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
Swift.precondition(condition, message, file: file, line: line)
}
@inline(__always) @noreturn func preconditionFailureAlt(@autoclosure message: () -> String = "") {
Swift.preconditionFailure(message, file: file, line: line)
}
#endif
您调用任何这些函数的所有实例现在都使用自定义实现。这样您在调试时仍然可以获取文件和行信息,但会阻止它出现在产品中。但是,您必须更改 to 的每个实例,precondition[Failure]
否则precondition[Failure]Alt
Swift 不能明确地推断出该函数。可以按Shift- Alt- Cmd-F在整个项目中进行搜索和替换
笔记
如果第三方框架使用了这些功能,而你在自己的机器上编译,那么路径显然会包含在框架产品中。为了防止这种情况,您要么必须使用预编译版本,要么自己使用模拟编译它。
如果任何其他自声明或第三方函数使用#file
,您显然也必须更改它,但这并不常见。
我不知道文件结构可能还有其他泄露的可能性。