打Log是我们debug时最简单朴素的方法,NSLog对于objc开发就像printf对于c一样重要。但在使用NSLog打印大量Log,尤其是在游戏开发时(如每一帧都打印数据),NSLog会明显的拖慢程序的运行速度(游戏帧速严重下滑)。本文探究了一下NSLog如此之慢的原因,尝试使用lldb断点调试器解决DebugLog问题。
基本上这种事情一定可以在Apple文档中找到,看NSLog的文档,第一句话就说:Logs an error message to the Apple System Log facility.,所以首先,NSLog就不是设计作为普通的debug log的,而是error log;其次,NSLog也并非是printf的简单封装,而是Apple System Log(后面简称ASL)的封装。
大概就是个系统级别的log工具吧,syslog的替代版,提供了一系列强大的log功能。不过一般我们接触不到,NSLog就对它提供了高层次的封装
意识大概是说,NSLog会向ASL写log,同时向Terminal写log,而且同时会出现在Console.app中(Mac自带软件,用NSLog打出的log在其中全部可见);不仅如此,每一次NSLog都会新建一个ASL client并向ASL守护进程发起连接,log之后再关闭连接。所以说,当这个过程出现N次时,消耗大量资源导致程序变慢也就不奇怪了。
NSLog有这样的消耗问题,那该怎么办呢?
拒绝残留的Log。现在项目都是多人共同开发,我们应该只把Log作为错误日志或者重要信息的日志使用,commit前请把自己调试的log去掉(尤其是在循环里写log的小伙伴,简直不能一起快乐的玩耍了)
release版本中消除Log。debug归debug,再慢也不能波及到release版本,用预编译宏过滤下就好。
是时候换个Log系统了,如CocoaLumberjack,自建一个简单的当然也挺好(其实为了项目需要自己也写了个小log系统,实现可以按名字和级别显示log和一些扩展功能,以后有机会分享下)
NSLog耗费比较大的资源
NSLog被设计为error log,是ASL的高层封装
在项目中避免提交commit自己的Debug log,release版本更要注意去除NSLog,可以使用自建的log系统或好用的log系统来替代NSLog
debug不应只局限于log满天飞,lldb断点调试是一个优秀的debug方法,需要再深入研究下