iOS程序猿iOS开发笔记我爱编程

Swift 中自定义Log

2018-04-16  本文已影响28人  LazyLoad

前言

在使用Objective-C开发过程中,我们经常要自定义Log,原因很简单:

几个问题

允许我卖个关子,先不谈,debug还是release该怎么自定义Log。先谈一下,我们打印的时候遇到的问题。根据问题来一步步解决
1、Swift中print函数,不会再占用很大的资源,但是在release模式下,确实没有必要打印Log,其实我想说,Swift 中print确实做了很多优化,但是也存在一些问题,看如下代码

print("123")

123
123

我在分别在两个函数里,打印了"123"字符串,可是我并不知道,"123"到底是在哪打印的,在哪个文件或者在哪个函数中,一脸懵逼
所以我想知道我在哪个文件中打印的这句话,Swift可以这样搞:

        let file = #file
        print(file)
结果:/Users/bh/Desktop/test/test/ViewController.swift

这样就可以把具体哪个文件打印出来了,就是那个绝对路径。
绝对路径很烦,因为前面那些xxx我根本不需要,所以我优化了一下,如下:

        let file = #file
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName)-123")

结果:
AppDelegate.swift-123
ViewController.swift-123

很明显,我知道了在哪个文件中打印了123。
2、我虽然知道了在哪个文件中打印了123,但是如果放在同一个文件中的两个方法里面呢?

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName)-123")
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName)-123")
    }

ViewController.swift-123
ViewController.swift-123

还是区别不出来,接下来我进一步优化,有两种方式,一种是

  override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent

        
        let funcName = #function
        print("\(fileName):[\(funcName)]-123")
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent
        
        let funcName = #function
        print("\(fileName):[\(funcName)]-123")
    }
    }

打印结果:
ViewController.swift:[viewDidLoad()]-123
ViewController.swift:[viewWillAppear]-123

还有另一种(个人偏爱这一种):

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(#line))-123")
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let file = #file
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(#line))-123")
    }

打印结果:

ViewController.swift:(19)-123
ViewController.swift:(27)-123

这种方式,是告诉咱们,在多少行打印,简洁。

3、接下来的问题是,我们不能每个方法里面都写这些代码,显得不专业,需要抽出一个方法来

func BHLog(file: String, line: Int) {
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(#line))-123")
    }

然后调用时候,BHLog(file: #file, line: #line) 这个样子,更烦了

我们接下来,利用Swift中的 参数默认值解决:

func BHLog(file: String = #file, line: Int = #line) {
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(line))-123")
    }

BHLog()

4、好像只剩下一下问题了,就是我们要打印的内容,我们不只是要打印String类型,可能是Int、Double或者是对象类型,所以我们需要再加个参数。

func BHLog<T>(_ message: T, file: String = #file, line: Int = #line) {
        let fileName = (file as NSString).lastPathComponent
        print("\(fileName):(\(line))-\(message)")
    }

泛型<T>,它代表着我们可以用T来代替实际类型,函数名后跟的那个 <T> 是函数定义的一个占位类型名,并不会查找T的具体类型。
这样就解决了。
5、剩下最后一个问题,我们有很多的类,不能够在每个类里都调用,这个函数,所以,我们利用Swift的全局函数,在任意一个类里面写个全局函数,就在所有的类中,可以调用了,我是写了个Global.swift 文件,你也可以卸载Appdelegate.swift中。

最后小尾巴

说了这么多,如何在Swift中,debug打印,而release中不打印呢,请继续看:


image.png
func BHLog<T>(_ message: T, file: String = #file, line: Int = #line) {
    
    #if DEBUG
    let fileName = (file as NSString).lastPathComponent
    print("\(fileName):(\(line))-\(message)")
    #endif
}

这样release就不会打印了,而在debug模式中会打印
结束,美滋滋!

上一篇 下一篇

猜你喜欢

热点阅读