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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM