zoukankan      html  css  js  c++  java
  • Objective-C与Swift下的自定义打印函数(Debug和Release)

    1.Objective-C  

      在使用Objective-C进行开发的过程中,为了Debug会不断的设置打印函数。如下图是我们经常用的,用来测试监听方法的实现与否:

    1     NSLog(@"%s", __func__);
    2     NSLog(@"%s", __FUNCTION__);

      需要说明的是,__func__和__FUNCTION__都是C的预定义符号,代表的含义完全相同,就是返回 类名+方法名 的字符串。

      注意:1.返回的字符串是C语言的字符串 char * 类型,注意占位符是 "%s"。

         2.两个预定义符号前后都是两个下划线,注意不要写成一个。

      打印结果:

    1 2016-11-25 09:53:05.769 RoonenSmartLifeSecondPhase[47510:1409025] -[JTSmartLifeViewController buttonDidPress:]
    2 2016-11-25 09:53:05.770 RoonenSmartLifeSecondPhase[47510:1409025] -[JTSmartLifeViewController buttonDidPress:]

      可以看到,完全相同。

      但是需要注意的一点是,我们的程序分为两种模式:Debug和Release。具体可以在这个位置看到:

      两种模式的意义从它们的命名上就明白了:1.Debug:调试 2.Release:发布 。区别很明显,Debug模式下自然是不考虑资源占用以发现Bug为目的,而发布模式下自然要最大化优化性能。

      那么我们再回头看打印这个函数:除错模式下,打印自然是十分有用的;发布模式下,打印就没什么用了,还大量占用系统资源。为什么?因为 NSLog() 这个函数,本质上就是在不停地拼接字符串。很明显我们在发布状态下是不能打印的。

      那么我们如何去在调试状态下让它打印,在发布状态下不让它打印呢?

      我们可以用下面这个宏来解决:

    1 /*** 日志 ***/
    2 // 若是在DEBUG模式下运行,则打印;若不是,则什么都不做
    3 #ifdef DEBUG
    4 #define JTLog(...) NSLog(__VA_ARGS__)
    5 #else
    6 #define JTLog(...)
    7 #endif

      其中需要注意的是:

      __VA_ARGS__:总体来说就是将左边宏中 ... 的内容原样抄写在右边 __VA_ARGS__ 所在的位置。它是一个可变参数的宏,是新的C99规范中新增的。

      好了,那么上面这个宏的定义就非常清晰了。若处于 DEBUG 这个宏生效的模式下(自然也就是Debug模式),那么调用 JTLog(...) 这个宏就与调用 NSLog(...) 完全一致;否则,调用 JTLog(...) 等于什么都不做。我们需要打印的时候,就直接调用 JTLog(...) 来代替 NSLog(...) 就可以了。功能实现了!

      等等!DEBUG这个宏是什么意思?

      我们试着 command+左键 这个宏,发现系统找不到这个宏所在的位置。为什么会这样?

      其实这个宏在这个位置:

      也就是 TARGETS --> Build Settings --> Apple LLVM 8.0 - Language - Modules --> Preprocessor Macros --> Debug 位置。

      我们可以看到,它默认设置了一个宏 DEBUG=1。而在Release模式下是没有这个宏的。其实这个宏就是在这里设置的,所以系统才会找不到。同时我们也可以在这里设置一些宏,格式就是:

      Macro=Value

      注意:这里设置的宏名不可以全是小写字母。

      这样就设置了一个其他人都找不到的宏了。并且你可以在任何地方调用它。但是我不建议这么做,假如你在这里定义了一堆宏,但是你同事或者接手代码的人一个都找不到,你会被骂的-.-

      就是这么简单。但最终还有一个问题。如何在所有的类中使用这个 JTLog(...) 呢?

      对,自然就是放在 PrefixHeader.pch 中啦~具体不详细介绍了,百度吧..

      最后,我们可以同样在 PrefixHeader.pch中声明这样一个宏,来快捷打印当前方法名:

    1 #define JTLogFunc JTLog(@"%s", __func__);

      调用的时候,分号都可以不写了。

     

    2.Swift

      对,其实现在开始才是文章的重点。。假如懂得如何实现Objective-C中自定义打印的道友,可以直接往下看;初学即Swift的道友推荐补习下Objective-C篇再搞定下面的东西,有些东西我就不重复介绍了。

      Swift中与Objective-C很大的区别在于:Swift中没有宏这个定义!如何是好?

      确实,Swift中默认没有宏这个定义方式,但其实我们还是可以自定义宏的。而且与上面的自定义宏的方式相同。

      就是这个位置。

      TARGETS --> Build Settings --> Swift Complier - Custom Flags --> Other Swift Flags --> DEBUG

      格式 -D DEBUGSWIFT 。也就是声明的宏之前要加一个这样的符号 -D 。它会自动分成两行显示。

      建议与上面Objective-C的 DEBUG 宏区分表示,以免混淆。

      宏有了,具体打印怎么写呢?

      非常简单。声明一个全局函数即可。

    1 func JTPrint<N>(message: N) {
    2     
    3     #if DEBUGSWIFT
    4     print(message)
    5   #endif
    6 }

      另外再说一句:把这个函数放在任意一个类的外面,即 class{ } 外面,就是全局函数了,全局变量也是一样的。

      或者你可以声明一个信息异常齐全的打印,使用预定义符添加一些其他你想要看到的信息。比如这样:

    1 func JTPrint<N>(message: N, fileName: String = #file, methodName: String = #function, lineNumber: Int = #line){
    2     
    3     #if DEBUGSWIFT // 若是Debug模式下,则打印
    4         
    5         print("(fileName as NSString)
    方法:(methodName)
    行号:(lineNumber)
    打印信息(message)");
    6     #endif
    7 }

      打印结果那是异常的酷炫:

    1 文件名:Controller/SmartScene-智能场景/SmartInHomeViewController.swift
    2 方法:viewDidLoad()
    3 行号:36
    4 打印信息:123
  • 相关阅读:
    自定义线性表
    网站关键词抓住热点话题获取长尾关键词 给网站增添流量(图)
    Hibernate常见注解说明
    面试问题java基础
    Spring常见的注解说明
    poj3268
    poj3273
    poj3250
    poj3277
    poj3253
  • 原文地址:https://www.cnblogs.com/SoulKai/p/6100723.html
Copyright © 2011-2022 走看看