1.Objective-C  

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

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

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

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

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

  打印结果:

 -- ::05.769 RoonenSmartLifeSecondPhase[:] -[JTSmartLifeViewController buttonDidPress:]
-- ::05.770 RoonenSmartLifeSecondPhase[:] -[JTSmartLifeViewController buttonDidPress:]

  可以看到,完全相同。

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

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

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

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

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

 /*** 日志 ***/
// 若是在DEBUG模式下运行,则打印;若不是,则什么都不做
#ifdef DEBUG
#define JTLog(...) NSLog(__VA_ARGS__)
#else
#define JTLog(...)
#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中声明这样一个宏,来快捷打印当前方法名:

 #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 宏区分表示,以免混淆。

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

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

 func JTPrint<N>(message: N) {

     #if DEBUGSWIFT
print(message)
  #endif
}

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

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

 func JTPrint<N>(message: N, fileName: String = #file, methodName: String = #function, lineNumber: Int = #line){

     #if DEBUGSWIFT // 若是Debug模式下,则打印

         print("\(fileName as NSString)\n方法:\(methodName)\n行号:\(lineNumber)\n打印信息\(message)");
#endif
}

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

 文件名:Controller/SmartScene-智能场景/SmartInHomeViewController.swift
方法:viewDidLoad()
行号:
打印信息:123


Objective-C与Swift下的自定义打印函数(Debug和Release)的更多相关文章

  1. PHP TP框架自定义打印函数P

    效果如下,有个灰色背景,也不一定是灰色可以改 代码: //传递数据以易于阅读的样式格式化后输出function p($data){ // 定义样式 $str='<pre style=" ...

  2. Swift技术之如何在iOS 8下使用Swift设计一个自定义的输入法 (主要是NSLayoutConstraint 的使用)

    当前位置: > Swift新手入门 > Swift技术之如何在iOS 8下使用Swift设计一个自定义的输入法 时间:2014-09-10 16:49来源:未知 作者:啊成 举报 点击:5 ...

  3. Swift 自定义打印方法

    Swift 自定义打印方法 代码如下 // MARK:- 自定义打印方法 func MLLog<T>(_ message : T, file : String = #file, funcN ...

  4. Swift下自定义xib添加到Storyboard

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/51657154 ...

  5. 关于Debug下的Log打印问题

    在项目中为了调试经常会用到Log打印,比如打印当前方法__func__, 对象,地址等等,所以项目最后每次运行调试控制台满满的都是打印日志,到release发布的时候,显然不太合适,这里其实可以用一个 ...

  6. iOS 11 导航栏 item 偏移问题 和 Swift 下 UIButton 设置 title、image 显示问题

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  7. WPF打印原理,自定义打印

    一.基础知识 1.System.Printing命名空间 我们可以先看一下System.Printing命名空间,东西其实很多,功能也非常强大,可以说能够控制打印的每一个细节,曾经对PrintDial ...

  8. Masonry 在swift下的使用

    Masonry在oc下使用很方便,但是在swift下,由于oc方法和property都可以使用.fuc的语法,swift下只有属性可以使用.property的语法,方法只能写成.func().因此在s ...

  9. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

随机推荐

  1. day7 面向对象编程

    编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种 ...

  2. TaintDroid:智能手机监控实时隐私信息流跟踪系统(三)

    4.3   原生代码标记传播 Native 代码是不受TaintDroid监控的.理想情况下,我们获得了相同的传播语义当使用相同的解释副本时.因此,为了精确的在Java层进行污点监控,我们定义了两个必 ...

  3. android JNI--- 搭建环境(1)

    搭建好我们的ndk开发环境,这部分网上资料一大堆,拿来主义~~~~ 工欲善其事必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android ...

  4. 【Android LibGDX游戏引擎开发教程】第07期:中文字体的显示和绘制(上)

    在字体的显示和绘制中,Libgdx的作者(Mario Zechner,美国人)给我们提供了一个非常好用的工具 ——Hiero,那么下面就来看看它具体的使用方法. 一.Hiero工具的使用 1.Hier ...

  5. 使用kettle工具将文本文件的内容插入Linux虚拟机下的mysql表中

    一.      解压kettle包 1.把包拷到Linux系统下 还有mysql的驱动包 2.解压zip后缀的包 输入命令:unzip /software/pdi-ce-7.0.0.0-25.zip ...

  6. BIOS详解:什么是BIOS ?BIOS的作用?CMOS及其与BIOS的关系?

    1.什么是BIOS ? BIOS是英文Basic Input Output System的缩略语,直译过来后中文名称就是基本输入输出系统.它的全称应该是ROM-BIOS,意思是只读存储器基本输入输出系 ...

  7. linux下测试宽带速度

    speedtest-cli是一个用Python编写的轻量级Linux命令行工具,在Python2.4至3.4版本下均可运行.它基于Speedtest.net的基础架构来测量网络的上/下行速率.安装sp ...

  8. [ios2] ios7UI适配 【转】

    http://blog.csdn.net/toss156/article/details/11843873#comments (1)如果应用程序始终隐藏 status bar 那么恭喜呢,你在UI上需 ...

  9. docker网络解析

    Docker概念和默认网络 什么是Docker网络呢?总的来说,网络中的容器们可以相互通信,网络外的又访问不了这些容器.具体来说,在一个网络中,它是一个容器的集合,在这个概念里面的一个容器,它会通过容 ...

  10. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...