内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

1.2监控print日志

2018-06-08 19:45 出处:清屏网 人气: 评论(0

前一章节我们分析了 NSLog 日志的监控,不过接触过Swift语言的同学都知道,Swift中大家一般都是用 print 来记录日志。当然,Swift并没有将 NSLog 给废弃掉。

NSLog In Swift

当然,Swift中我们也可以用 NSLog 来做日志记录,但是Swift对 NSLog 做过优化。笔者发现Swift中调用 NSLog 方法,它并不会想Objective-C中调用 NSLog 方法那样将日志放入 Apple System Log 中,模拟器环境下除外。也就是说我们在真实环境下并不能通过 ALS 获取 NSLog 的日志信息。因此我们需要寻找其他的办法。

自定义print方法

我们来看看Swift中 print 方法的定义:

public func print(_ items: Any..., separator: String = default, terminator: String = default)

其中 separator 的默认值是一个" "(空格字符串)。 terminator 的默认值是"\n"(回车符)。

我们自定义的 print 方法不能完全和Swift的一样,不然编译器会给你一个报错 Ambiguous use of 'print(_:separator:terminator:)' ,因为两个API一模一样,编译器就不知道去链接哪个API了。

不过我们可以把默认值去掉,只需要一个item参数就好:

public func print(_ items: Any...) {
    //TODO: Custom Actions
    Swift.print(items)
}

这样,我们只需要在使用print方法的swift文件中,import我们这个自定义api的库就好了。然后将 TODO: Custom Actions 中放入我们的日志监控操作即可。

自定义日志框架

自定义print方法固然不错,但是使用者很容易忘了import我们这个自定义api的库,Swift中也没有预加载的功能,因此使用者很容易忘记做import操作,导致监控不到。而且单独一个print方法无法优雅的区分日志的类型,比如log,warning,error等。更不能获取文件名,方法名等日志辅助信息。因此我们何尝不自定义一个轻量级的日志框架呢。

该日志框架大家可通过 https://github.com/zixun/Log4G 下载,文中由于篇幅的原因,只会列出关键代码,建议将开源源码下载后对照着源码查看,会更便于理解。

我们先来看一张 Log4G 的简要设计图:

从图上我们可以看出,我们对外有三个接口,分别是 log() , warning()error() 。他们内部都会调用一个不公开的接口 record() ,当然在方法中会自动获取日志的文件(file),行数(line),方法名(function)以及线程(thread),然后传递给 record() 方法, record() 方法内部所有的操作都在一个指定的queue中进行,可以防止多线程的问题。 record() 会做两件事,一个就是调用系统的 print() 函数,还有一个就是通知 Log4g 内部维护的delegate数组,告诉日志监听者们新的日志信息。

我们先来看看 log() 的实现:

/// record a log type message
///
/// - Parameters:
///   - message: log message
///   - file: file which call the api
///   - line: line number at file which call the api
///   - function: function name which call the api
open class func log(_ message: Any = "",
                    file: String = #file,
                    line: Int = #line,
                    function: String = #function) {
    self.shared.record(type: .log,
                       thread: Thread.current,
                       message: "\(message)",
                       file: file,
                       line: line,
                       function: function)
}

我们通过 #file , #line , #function 可以自动获取调用API时候的文件名,行数以及方法名,不需要调用者参与。然后通过 Thread.current 拿到当前线程,一并传递给 record 方法。这样调用者只需要传递日志即可,其他一切都是自动。

warning()error() 原理一致,那我们来看看 record() 方法:

```swift

/// record message base function

///

/// - Parameters:

/// - type: log type

/// - thread: thread which log the messsage

/// - message: log message

/// - file: file which call the api

/// - line: line number at file which call the api

/// - function: function name which call the api

private func record(type:Log4gType,


分享给小伙伴们:
本文标签: print

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号