swift LOG 输出

Log 输出是程序开发中很重要的组成部分,虽然它并不是直接的业务代码,但是却可以忠实地反映我们的程序是如何工作的,以及记录程序运行的过程中发生了什么。

在 Swift 中,最简单的输出方法就是使用print,在我们关心的地方输出字符串和值。但是这并不够,试想一下当程序变得非常复杂的时候,我们可能会输出很多内容,而想在其中寻找到我们希望的输出其实并不容易。我们往往需要更好更精确的输出,这包括输出这个 log 的文件,调用的行号以及所处的方法名字等等。

我们当然可以在print的时候将当前的文件名字和那些必要的信息作为参数同我们的消息一起进行打印:

// Test.swift
func method() {
    //...
    print("文件名:Test.swift,方法名:method,这是一条输出")
    //...
}

但是这显然非常麻烦,每次输入文件名和方法名不说,随着代码的改变,这些 Log 的位置也可能发生改变,这时我们可能还需要不断地去维护这些输出,代价实在太大。

在 Swift 中,编译器为我们准备了几个很有用的编译符号,用来处理类似这样的需求,它们分别是:

#column
符号 类型 描述
#file String 包含这个符号的文件的路径
#line Int 符号出现处的行号
Int 符号出现处的列
#function String 包含这个符号的方法名字

因此,我们可以通过使用这些符号来写一个好一些的 Log 输出方法:

func printLog<T>(message: T, file: String = #file, method: String = #function, line: Int = #line) { "\((file as NSString).lastPathComponent)[\(line],method: message") }

这样,在进行 log 的时候我们只需要使用这个方法就能完成文件名,行号以及方法名的输出了。最棒的是,我们不再需要对这样的输出进行维护,无论在哪里它都能正确地输出各个参数:

//... printLog("这是一条输出") //... } // 输出: // Test.swift[62],method(): 这是一条输出

另外,对于 log 输出更多地其实是用在程序开发和调试的过程中的,过多的输出有可能对运行的性能造成影响。在 Release 版本中关闭掉向控制台的输出也是软件开发中一种常见的做法。如果我们在开发中就注意使用了统一的 log 输出的话,这就变得非常简单了。使用条件编译的方法,我们可以添加条件,并设置合适的编译配置,使printLog的内容在 Release 时被去掉,从而成为一个空方法:

line: Int = #line) { #if DEBUG ") #endif }

新版本的 LLVM 编译器在遇到这个空方法时,甚至会直接将这个方法整个去掉,完全不去调用它,从而实现零成本。

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...