做者:Andyy Hope,原文連接,原文日期:2016-04-14
譯者:SketchK;校對:Crystal Sun;定稿:CMBgit
時尚日誌,由你作主程序員
在以前的文章中,咱們討論了在輸出日誌中使用 emojis 的好處,它能夠幫助咱們更好的去消化和吸取大量的信息,不過我提供的實現方式並不怎麼樣,沒有足夠多的例子供你將其應用在本身的代碼中。github
我將遵照以前的約定繼續討論這個話題,向你展現如何使用 emojis 來實現輸出日誌的功能,只需在 print
函數上再多花費一點兒工夫。swift
在接下來的文章中,我會打破 Swift 的命名規範,這樣作我可不缺理由。爲了下降新方案的成本, 要在儘量減小鍵盤敲擊次數的狀況下達到一樣的目標,好比字母大小寫和標題大小寫的問題。無論怎麼樣,若是看到文章的最後,你還在爲一些細節而糾結的話, 你絕對應該把它們改爲你想要的樣子。xcode
enum log { }
這裏使用枚舉類型代替類或結構的緣由不少。緣由之一是,咱們永遠不須要實例化一個日誌。選擇枚舉而不是函數,是想確保實現一個安全的日誌輸出方案。不用着急,一會你就會明白我所說的「安全」的含義了.安全
enum log { case ln(_ line: String) case url(_ url: String) case obj(_ any: AnyObject) }
可能有些人還不知道 ln
(line) 曾經在 swift 語言中出現過。 print()
在 Swift 2.0 以後替代了 println()
, 且主要用於日誌輸出。我在這裏舉了一些例子來解釋 log 枚舉的可擴展性。app
要先爲每個枚舉值設置關聯值,畢竟得現有東西才能輸出日誌吧?請注意,這裏忽略了參數標籤,由於已經使用參數名稱來描述函數的參數了。框架
看一下目前的狀況吧:函數
print(log.ln(「Hello World」)) // ln("Hello World") print("Hello World") // "Hello World"
嗯,看樣子彷佛是完成了。但這看起來並非一個能夠替代 print
的方案。主要緣由有這些:工具
仍是要敲擊不少次鍵盤
除了原始信息外還有許多沒必要要的內容
外表不怎麼樣
沒有一個 emojis
千言萬語,就一句:「這方案太糟糕了」
如今須要完善上面的五個問題, 以便實現以前定下的目標.
postfix operator / { }
先假定大家大多數人在這以前都沒有遇到過自定義運算符的需求。不要緊,我也是最近才用上這個功能, 不過用的也不是太多.
要建立一個 postfix
後置運算符,展現的內容會出如今運算符的左側,想讓它出如今日誌代碼的後面, 只用敲擊一次鍵盤就能實現。
選擇 /
符號是由於它最接近註釋符號但不會真正產生註釋,另外它也是少數幾個不用 shift 鍵來就能夠直接打出來字符。
...感受本身就像是政客,在不停的想辦法減小實現預算。
postfix func / (target: log) { switch target { case ln(let line): log("✏️", line) case url(let url): log("?", url) case obj(let object): log("?", object) }
這段代碼看起來像聲明,有代碼主體(body), 增長了在約束,確保自定義操做符接收的參數是 log 枚舉值,這在必定程度上符合我所說的的「安全代碼」。「安全代碼」這個概念還體如今使用枚舉替代類或結構體,由於枚舉中的 switch 必定會把全部狀況都檢查一遍。這樣,每次想在輸出日誌中添加一個新的 emoji 時, 也必須將其添加到操做符中的 switch 語句裏。
private func log<T>(emoji: String, _ object: T) { print(emoji + 「 「 + String(object)) }
終於獲得了這個看似很是簡單 log
函數。它是一個私有函數,可不被 .swift
文件以外的任何東西訪問到,另外它的第二個參數是一個泛型,這個參數可以接受任意類型的值。
正如你所看到的同樣,這是一個至關簡單的打印語句,把 emoji 表情和對象用空格連起來。
log.ln(「Pretty」)/ ✏️ Pretty log.url(url)/ ? http://www.andyyhope.com log.obj(date)/ ? 2016–04–02 23:23:05 +0000 Maybe i should use a screenshot here instead?
如今咱們有一個能夠替代系統原有輸出日誌的方案了, 新方案只須要進行兩次敲擊,相比其餘的日誌輸出工具,脫穎而出、暢快淋漓。不過這還沒完呢...
大多數的程序員都會有這麼一個共識,就是調用 print 方法會下降 app 的性能。若是含有 print 的代碼散落在程序的不一樣地方, 在 debug 的時候仍是能夠接受, 但是要把 app 上傳到 AppStore 時,最好仍是移除這些內容。
"你是在說,每一次我都必須在提交 App Store 前註釋掉全部的 print 語句, 而後再在 debug 的時候把它們恢復回來麼?" —— 你
能夠用 Xcode 給工程建立配置文件, 在默認狀況下 Xcode 會爲每一個工程提供兩個配置文件 : Debug 和 Release.
在使用模擬器或用 USB 鏈接真機時,默認模式是 debug,用手機打開從 AppStore 下載的 app 時,默認模式是 relsase。
把剛纔寫好的代碼放入到用於標識 debug 狀態的預編譯標識符裏, 這樣就不用在每次打包的時候對這些代碼進行註釋/恢復/增長/刪除等操做。至關於告訴編譯器:「Hi,哥們,除了 release 模式下, 你都得運行這段代碼!」
點擊 Project Navigator 圖標
點擊 Project 名稱
點擊 Build Settings 按鈕
搜索 「Compiler Flag」
展開 「Other C Flags」
點擊 「+」 按鈕
輸入 「-D DEBUG」
最終把整個 print 函數放到預編譯的標識符中。
private func log<T>(emoji: String, _ object: T) { #if DEBUG print(emoji + 「 「 + String(object)) #endif }
哦了!如今只有在開發狀態下 print 纔會生效。把 build configuration scheme 設置改成Release,運行 app,這樣就能夠檢測以前的操做是否成功,固然別忘了檢測完把狀態切回到 Debug 模式。
讀到這, 也許會想:「這些個點子太好了, 若是 Andyy 將這些功能弄成一個...」,但事實是這樣作並很差。
緣由就是, 假如我提供了上面三種方式中的任意一種, 那麼每當你想利用它作日誌輸出的時候,你就必須在 Swift 文件裏引入這個庫, 這樣作實在太傻了, 還須要作一些額外的操做來管理它們。這也是爲何許多 NSLog 的替代品在 Objective-C 中表現很差的緣由。
import Log // 這看起來像坨 ?
我專門提供了一個 playground 文件,可以讓你測試一下今天所讀到的所有內容,若是想使用這個文件,只須要將 log.swift
文件拖入到工程中便可。另外在示例代碼中會有一些額外的枚舉值, 或許你會發現這些額外的例子對你的平常工做頗有用, 若是是這樣的話,拿走不謝!
示例代碼能夠在 Github 上下載到.
就像以前同樣, 若是你喜歡今天讀到的內容或者親手實現了它,請記得發我一個 tweet。很渴望聽到大家的聲音, 讓我很受用.
本文由 SwiftGG 翻譯組翻譯,已經得到做者翻譯受權,最新文章請訪問 http://swift.gg。http://swift.gg。