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)\n方法:\(methodName)\n行号:\(lineNumber)\n打印信息\(message)");
6     #endif
7 }

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

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

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 28.0px Menlo; color: #1d9421 }
span.s1 { }
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 28.0px Menlo }
span.s1 { }

时间: 2024-08-15 08:18:57

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

php - 获取函数参数的个数以及自定义打印函数

通常用来测试打印出多个参数时使用 function echo_para($split,$a,$b=0,$c=0,$d=0,$e=0,$f=0,$g=0,$h=0,$i=0,$j=0,$k=0,$l=0,$m=0,$n=0) { //获取参数总数 $n = func_num_args(); $str = ""; for($i = 1;$i< $n;$i++) { $str .= func_get_arg($i) . $split; } return $str; }

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

效果如下,有个灰色背景,也不一定是灰色可以改 代码: //传递数据以易于阅读的样式格式化后输出function p($data){ // 定义样式 $str='<pre style="display: block;padding: 9.5px;margin: 44px 0 0 0;font-size: 13px;line-height: 1.42857;color: #333;word-break: break-all;word-wrap: break-word;background-co

自定义 打印 成功跳转 失败返回 函数

/** * 自定义打印函数 */function p ($arr) {    echo "<pre>";    print_r($arr);    echo "</pre>";} /** * 成功跳转函数 */ function success ($url, $msg) {    header('Content-Type:text/html;charset=utf-8');    $url = site_url($url);   //ci框架

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

当前位置: > Swift新手入门 > Swift技术之如何在iOS 8下使用Swift设计一个自定义的输入法 时间:2014-09-10 16:49来源:未知 作者:啊成 举报 点击:562次 我会复习一下有关键盘扩展的内容,然后通过使用iOS 8中的新应用扩展API的设计一个摩斯码的输入法.完成这个教程大约需要花费20分钟.完整代码 概览 通过使用自定义输入法替换系统输入法,用户可以实现一些特别的功能.例如一个特别新颖的输入方式,或输入iOS原生并不支持的语言.自定义输入法的基本功能很简单

Swift 自定义打印方法

#代码如下 // MARK:- 自定义打印方法 func MLLog<T>(_ message : T, file : String = #file, funcName : String = #function, lineNum : Int = #line) { #if DEBUG // 创建一个日期格式器 let dformatter = DateFormatter() // 为日期格式器设置格式字符串 dformatter.dateFormat = "yyyy-MM-dd HH:

分享一个自定义打印套打方案(一),概述

最近项目中需要实现单据套打的功能,实现后,留此日记以备忘,同时为有类似需求的同学提供一种解决方案. 原始需求: 1. 打印模板支持灵活自定义,支持可视化设置(含设置打印项是否打印,及位置,大小,字体等…). 2. 支持自定义打印项. 3. 常规的打印项设置(如自动打印小计/合计,表头表尾等…) 4. 在设置模板的时候,支持实时预览. 首先,先上个图, 给大家看一下打印套打模板的大致效果图,各位同学看着顺眼再往下看. 接下来,我们简单的来讨论一下如何实现这个需求,简单分析一下,在这个功能中,可能需

分享一个自定义打印套打方案(二),扩展Panel,以支持鼠标随意拖动

接上一章节,本篇主要介绍一种支持鼠标随意拖动Panel内部控件位置的方法.为了简单起见,这里我们不妨就暂称我们将要扩展的Panel容器名称为 MoveControlPanel,该容器至少需要实现以下功能 1. 识别当前鼠标位置,是否处于某个内部组件的边框位置,以让鼠标显示出对应的图标(拉伸,移动-) 2.移动鼠标以改变内部某个组件的大小及坐标, 3.保存容器内每个组件的当前坐标及大小. 为了便于描述当前光标状态,我们不妨定义一个枚举.姑且称其为 EMousePointPosition, 其至少应

WPF打印原理,自定义打印

一.基础知识 1.System.Printing命名空间 我们可以先看一下System.Printing命名空间,东西其实很多,功能也非常强大,可以说能够控制打印的每一个细节,曾经对PrintDialog失望的我看到了一丝曙光. 2.PrintDialog 可以看到PrintDialog除了构造函数有三个方法和一堆属性,PrintDocument接受一个分页器(DocumentPaginator,稍后介绍),PrintVisual可以打印Visual,也就是WPF中的大部分继承自Visual类的

[Linux]一些Debian系统下的自定义

163镜像的sources.list deb http://mirrors.163.com/debian/ wheezy main non-free contrib deb http://mirrors.163.com/debian/ wheezy-proposed-updates main non-free contrib deb-src http://mirrors.163.com/debian/ wheezy main non-free contrib deb-src http://mir