Swift中assert与precondition的file、line参数用途及显示问题咨询
关于Swift中assert/precondition的file和line参数的解惑
嘿,这个问题我之前调试的时候也纠结过,来给你掰扯清楚~
首先得明确:file和line参数默认是不需要手动传递的!Swift在编译时会自动用特殊字面量#file(当前文件路径)和#line(当前行号)填充这两个参数的默认值,你不用自己写。
为什么控制台没显示文件/行号?
大概率是编译模式的问题:
assert只在Debug模式下生效,Release模式会被编译器直接移除,所以不会有任何输出。- 即使是Debug模式,如果你在Xcode的Build Settings里把
ENABLE_ASSERTIONS设成了NO,断言也不会触发。默认Debug模式下这个选项是YES,Release是NO。
举个最简单的例子,在ViewController.swift的第20行写:
assert(1 + 1 == 3, "这明显不对啊")
Debug模式运行后,控制台会输出类似这样的信息:
Assertion failed: 这明显不对啊: file /Users/xxx/YourProject/ViewController.swift, line 20
那file和line参数什么时候需要手动用?
主要场景是封装自定义断言工具函数的时候。比如你想写一个自己的断言函数,但是希望断言失败时,错误信息指向调用你这个函数的代码行,而不是你函数内部的行号。
举个例子:
// 自定义断言函数 func myAppAssert(_ condition: Bool, errorMessage: String = "断言失败", file: StaticString = #file, line: UInt = #line) { // 把接收的file和line传给系统的assert assert(condition, errorMessage, file: file, line: line) } // 在ViewController.swift第30行调用 myAppAssert(2 + 2 == 5, errorMessage: "数学没学好啊")
这时候触发断言,控制台显示的是第30行(调用myAppAssert的位置),而不是myAppAssert内部调用assert的那一行——这就是手动传递file和line的核心作用:让错误定位更精准,指向真正出问题的调用点。
再补充下precondition的情况
precondition和assert的file/line参数逻辑完全一样,区别只是precondition在Release模式下也会触发程序终止(用来检查那些程序运行绝对不能违反的条件),Debug模式下同样会输出带文件和行号的详细信息。
内容的提问来源于stack exchange,提问作者KiranMayee Maddi
相关产品推荐
相关产品推荐

