Swift vs. Objective-C:未來看好Swift的十個理由
英文原文:Swift vs. Objective-C: 10 reasons the future favors Swift
是時候使用易入手又全面的 Swif 語言為 iOS 和 mac OS X 做應用開發了。
雖然編程語言不會那么容易消逝,但堅持衰落范例的開發小組正在這么做。如果你正為移動設備開發應用程序,并且你還沒有研究 Swift,那么注意:當 Swift 涉及到 Mac、iPhone、ipad、Apple Watch 和未來設備的應用開發時,它不僅會排擠掉 Objective-C,而且還會取代在 Apple 平臺中做嵌入式開發的C語言。
由于幾個關鍵特性,在未來幾年,Swift 有很大潛力成為創造身臨其境的、響應迅速的、面向用戶的應用程序的實際編程語言。
蘋果公司似乎在 Swift 上還有更大的目標。它的編譯器性能和開發語言都被優化了,蘋果公司在 Swift 的文檔中暗示 Swift 被設計成小能(顯示)“hello,world”,大能(完成)整個操作系統。蘋果公司還沒把這門語言的目標說全,Xcode6,Playgrounds 和 Swift 的推出就一起揭露蘋果的意圖:更簡單的應用開發,更易用的開發工具鏈。
這是從現在起使用 Swift 工作,并走在比賽前列的 10 個原因。
1. Swift 容易閱讀
如你所能預計到的一門基于 C 構建的語言,Objective-C 身上所有的毒疣子都有。為了將關鍵詞和類型同C的類型作區分,Objective-C 使用@符號引入了新的關鍵詞。因為 Swift 不是基于C構建的,它同意了所有的關鍵詞,并將 Objective-C 類型和對象相關的關鍵詞前面大量的@符號移除了.
Swift 丟棄了遺留下來的約定。因而你不再需要行尾的分號,以及 if/else 語句中圍繞條件表達式的括弧。另外一個大變化就是方法的調用不再互相嵌套成中括號的深坑 -- 再見吧,[[[ ]]]。Swift 中的方法和函數的調用使用行業內標準的在一對括弧內使用逗號分隔的參數列表。這樣做的結果就是一種帶有簡化了句法和語法的更加干凈有表現力的語言。
除了其它當代流行的編程語言之外,Swift 更像是自然的英語了。這種可讀性是的其很容易能被其它來自 JavaScript,Java,Python,C#,以及 C++ 的開發者納入到他們的工具鏈之中 -- 一點也不像 Objective-C 這只笨笨的黃小鴨。
2. Swift 更易于維護
歷史遺留問題會讓 Objective-C 越來越倒退 -- C 沒有演進的話,這個語言也就跟著無法進行演進。C 需要程序員維護兩套代碼文件,以優化構建的時間以及創建可執行 app 的效率, 這種需要延續到了 Objective-C 上。
Swift 丟掉了對著倆文件的要求。Swift1.2 中 Xcode 和 LLVM 編譯器可以自動計算出以來并執行增量構建。如此,將內容清單 (頭文件) 同內容主體(實現文件)相分離。Swift 將 Objective-C 頭文件(.h) 和實現文件 (.m) 合并成了一個代碼文件 (.swift)。
Objective-C 的兩份文件系統存在強加給程序員的額外工作 -- 而這些工作會讓程序員難免分心而不能顧全大局. 在 Objective-C 中你不得不手動去同步文件之間的方法名稱和注釋, 有時候要寄希望于一個約定好的標準,不過除非團隊的規矩和代碼審查制度到位,否則這是不會為你提供什么保障的。
Xcode 和 LLVM 編譯器可以在幕后做一些工作來減輕程序員的工作負擔. 使用 Swift, 程序員可以少做些費腦力的記憶性工作,從而能在創建 app 邏輯的工作上面贏得更多的時間. Swift 為我們程序員裁掉了那些樣板式的工作,同時對代碼、注釋以及所要支持的特性的質量都有所提升。
3. Swift 更加安全
Objective-C 有意思的一個方面是指針 -- 特別是 nil (null) 指針 -- 它們被處理的方式. 在 Objective 中-C, 如果你調用方法的是一個值為 nil (未初始化)的指針變量,什么事情都會不發生. 表達式或者一行操作變成了一項空操作(no-operation (no-op)), 而這就使得其看起來會有不會奔潰的好處, 但其實它已經變成了一個巨大的 bug 來源. no-op 會導致不可預測的行為, 這是程序員在嘗試找出并修復某種隨機的奔潰,或者要停止反常的行為時所要面對的敵人。
在 Swift 代碼中的可選類型使得一個 nil 可選值的可能性變得非常的明確, 這意味它能在你寫下一段糟糕的代碼時會生成一個編譯器錯誤. 這就建立了一種短程反饋的循環,可以讓程序員帶著目標去寫代碼. 問題在代碼被寫就時就可以被修復, 這大大節省了你要在修復有關來自 Objective-C 指針邏輯的 bug 時需要耗費的時間和金錢。
在 Objective-C 的傳統中, 如果某個值返回自一個方法, (使用注釋以及方法的命名約定來)說明指針變量被返回的行為是程序員的責任.在 Swift 中, 可選類型和值類型使得方法定義中值是否存在,或者其有可能是可選的(即值可能存在也可能為 nil),這些問題都是很明確清楚的。
為了提供對行為的預測,Swift 會在 nil 可選值被使用時觸發一次運行時崩潰。 崩潰提供的就是一種一致的行為,它能減輕修復 bug 過程的壓力,因為它會直白地強制讓程序員修復好這個問題. Swift 運行時崩潰的時候會停在 nil 可選值被使用到的那行代碼處。這就意味著 bug 能更早的被修復,并能在 Swift 代碼中被完全的規避掉。
4. Swift 的內存管理是統一化的
Swift 以一種 Objective-C 從未有過的方式進行了統一。對自動引用計數 (ARC) 的支持是在整個過程化的和面向對象的代碼路徑上完成的。在。Objective-C。中, ARC 在 Cocoa API 和面向對象代碼中獲得支持;然而它并不支持過程式的 C 語言代碼和像 Core Graphics 這樣的 API。這意味著在使用 Core Graphics API 以及其它 iOS 上的底層 API 時,內存管控的處理都是程序員的責任。程序員在 Objective-C 上會遇到的大量內存溢出問題在 Swift 上是不可能的。
程序員不應該為他或她創建的數字對象去考慮內存的問題。因為 ARC 在編譯時就處理了所有的內存管理事務, 內存管理所有消耗的腦力現在可以被用來專注于核心的應用邏輯以及新的功能特性。因為 Swift 中的 ARC 在過程式的和面向對象的代碼中都能起作用,它也就不再需要程序員進行心理上的上下文切換了, 即使是他們在編寫要觸及底層 API 的代碼時也不需要 -- 這在目前版本的 Objective-C 中就是一個實實在在的問題。
自動和高性能的內存管理是一個已經被解決的問題,而蘋果公司已經證明了這個問題的解決可以提高生產力. 另外一個副作用就是 Objective-C 和 Swift 不會像 Java,Go 或者 C# 那樣遇到垃圾收集器針對沒有被使用的內存運行清理作業的情況. 這對于那些將會被用于相應圖形和用戶輸入的編程語言而言就是一個非常重要的要素, 特別是在諸如 iPhone、Apple Watch 以及 iPad 這樣的(如果響應滯后就會讓用戶感知上以為應用是壞的)觸摸屏設備上。
5. Swift 代碼更少
Swift 減少了重復性語句和字符串操作所需要的代碼量。在 Objective-C 中, 使用文本字符串將兩塊信息組合起來的操作非常繁瑣。Swift 采用當代編程語言的特性,比如使用“+”操作符將兩個字符串加到一起,這在 Objective-C 中是沒有。像這樣支持對字符和字串的組合對于任何要在屏幕上向用戶展示文本的編程語言的基礎設施。
Swift 中的類型系統減少了代碼語句的復雜性--作為編譯器可以理解的類型。比如,Objective-C 要求程序員記住特殊字符標記(%s,%d,%@)并且提供了一個用逗號分隔的變量來代替每個標記。Swift 支持字符串插入,這就消除了需要記住的標記和允許程序員直接插入變量到面向用戶的字符串中,比如標簽或者按鈕的標題。這類推理系統和字符串插入減少錯誤來 源在 Objective-C 中都是很常見的。
在 Objective—C中,搞亂了順序或者使用了錯誤字符串標記會造成 app 崩潰。這里,Swift 再次將你從反鎖的工作中解放出來,翻譯成更少要編寫的代碼(代碼現在已經不容易出錯)因為它的對處理文本字符串和數據的內嵌支持。
6. Swift 更快
刪除遺留下來的C語言約定大大提升了引擎蓋之下 Swift 的性能. Swift 代碼性能的基準測試一直都瞄向蘋果公司所致力于的 Swift 運行 app 邏輯的速度提升。
根據靈長類動物研究所(Primate Lab)——時下流行的 GeekBench 性能工具的創造者——的調查, 2014 年 12 月中使用曼德爾布羅算法(Mandelbrot algorithm)進行計算密集型任務的性能上,Swift 已經逼近 C++ 的表現了。
在 2015 年 2 月,靈長類動物研究所發現 Xcode 6.3 測試版提升了 Swift 在 GEMM 算法上的性能 -- 這是一種受制于內存限制的算法,需要對大型數組進行順序訪問 -- 有 1.4 倍. 初始的 FFT 實現 -- 這是一種會對大型數組進行隨機訪問的受限于內存的算法 -- 擁有 2.6 倍的性能提升。
通過應用最佳實踐,可以觀察到更進一步的性能提升, 結果是 FFT 算法上 8.5 倍的性能 (差上 C++ 1.1 倍)。這些改進也使得 Swift 在曼德爾布羅算法上實際超越了 C++ 1.03 倍。
Swift 在 FFT 和曼德爾布羅算法上幾乎能與 C++ 比肩。根據 Primate Labs 的研究發現,GEMM 算法的性能表現說明 Swift 編譯器還不能實現 C++ 編譯器支持的矢量代碼 -- 所以 Swift 的下一個版本可能會比較容易的獲得一次性能提升。
7. 開源項目中更少的名稱沖突
Objective-C 代碼中一直令人很困擾的問題就是缺乏對命名空間的正式支持, 它是 C++ 處理文件名沖突的解決方案。當名稱沖突發生在 Objective-C 中時,就會是一個連接器錯誤,會導致 app 無法運行。解決的辦法倒是有,可它們都有潛在的隱患。一般的約定是使用兩到三個字母前綴來區分編寫的 Objective-C 代碼, 比方說,通過 非死book 來展現出你自己的代碼。
Swift 提供了隱含的命名空間,允許相同的代碼文件存在于多個項目,而不會造成構建失敗,或者需要向 NSString (Next Step -- Steve Jobs 被 Apple 炒魷魚之后創建的公司) 或者 CGPoint (Core Graphics)這樣的名稱。最終,Swift 中的這一特性使得開發者更加的有生產力,并且也意味著他們沒必要再做 Objective-C 需要的備忘式記憶工作。在簡單如 Array,Dictionary 以及 String 這樣的名字中你可以看到 Swift 的影響力,而不是脫胎于缺少命名空間的 Objective-C 中的 NSArray、NSDictionary 以及 NSString。
Swift 的命名空間是基于一份代碼文件所屬的目標位置。這就意味可以使用命名空間標識來區分出不同的類和值。Swift 中的這個改變很大,它極大的方便了將開發員項目、框架以及庫集成到你代碼中來的操作。命名空間使得在集成開源項目時,不用擔心來自不同軟件公司的同名代碼 文件會發生沖突。現在 非死book 和蘋果公司可以同時使用一個叫做 FlyingCar.swift 的對象代碼文件,不會有任何錯誤或者失敗。
8. Swift 支持動態庫
Swift 中沒有受到足夠重視的一個最大的問題是靜態庫向動態庫的切換,其在主要發布版(iOS8,iOS7 等等)會被更新。動態庫是可以被鏈接到 app 的可執行代碼塊。這一特性可以讓現有的 Swift 應用可以鏈接到隨著時間推移所產生的更新版本的 Swift 語言。
開發者將 app 連同庫文件一并提交,它們都用開發者證書打上了數字簽名,以確保完整性 (你好, NSA)。這就意味著 Swift 可以比 iOS 更快地進化,對于一種現代編程語言而言這是必要的。對庫文件的修改可以被全部引入 AppStore 上某個 app 的最新更新中,一起運行起來都如此簡單。
動態庫在 iOS 上從未受到支持,直到 Swift 和 iOS 8 的發布,盡管已經在 Mac 獲得支持很久了。動態庫處在應用可執行文件之外,不過會被包含在從 AppStore 上下載的應用包中。它減小了 app 被加載到內存中的初始大小,因為外部代碼只在被用到時才會被鏈接進來。
移動應用程序或者是 Apple Watch 上的嵌入式應用所具有的延遲加載能力,將提升應用面向用戶的感知性能。這是使得 iOS 生態系統更具感官上的響應性的區別之一。蘋果公司原先只專注于運行時加載資料和資源,現在代碼的編譯和鏈接也可以在運行時進行。運行時加載減少的等待時 間,直到資源需要被用于展示在屏幕上時,才會被加載進來。
Swift 中的動態庫讓編程語言的修改升級比以往更快的傳播出去成為了可能。用戶不在需要等待指定的 iOS 版本發布才能享受到 Apple 引入 Swift 中的性能和可靠性改進。
9. Swift Playgrounds 鼓勵交互式編碼
Swift 新引入的 Playgrounds 是有經驗的開發者的福音。Playgrounds 的靈感來自于蘋果公司前雇員 Brett Victor 的工作。Playgrounds 可以讓程序員用比如說 5 到 20 行代碼來測試一種新的算法或者圖形程序,不用去創建一個完整的 iPhone 應用。
蘋果公司已經將內聯代碼執行操作加入到了 Playgrounds 中,以幫助程序員創建代碼塊或者編寫某種算法時獲得反饋。這樣的反饋循環可以提升代碼編寫的速度,因為傳統程序員所需要的心智模型已經為 Playground 的數據可視化形式所替代。編程是一個反復的過程,任何可能壓力上的減輕或者創造的補充都會使得開發者更具生產力,并能釋放出他們的精力來解決更大的問題, 而不是死盯著傳統編譯器來增加程序員的繁瑣細節。
注意:據我教授新手程序員的經驗,Playgrounds 對于入門者而言不會像對有經驗的程序員那么有用。如果只是簡單的展示 Swift 中一個變量是如何工作的,Playggrounds 顯然不能對幫助新手理解對于一個浮點指針變量與一個整型變量的需要。當你要展示一個能記憶你最后在 非死book 新聞提要中的滾動位置時,這種需要才會變得明顯。對于新手而言,“為什么”這個問題只能用一個可以運行示例:也就是一個 iPhone 應用,來回答。
10. Swift 是一個你可以影響的未來
Objective-C 沒有任何出路,你將不會看到它發生改變,我們要感謝 Swift 的引入. 一些 Swift 特性可能會集成到 Objective-C, 但 Objective-C 的 C 語言遺留物還是注定了它只能吸收那么點 Swift 的好東西。
Swift 向開發者社區提供了一個直接的方式,去影響一門語言,它將會被用于應用的創建,嵌入式系統(如果蘋果公司向第三方的嵌入式框架和芯片進行了授權)以及像 Apple Watch 這樣的設備.
蘋果公司專注于提供最佳的消費者體驗,而且只構建值得注意的功能特性. 隨著 Xcode6.3 中 Swfit1.2 的發布,蘋果公司已經利用流行的 Apple Bug Reporter 工具修復了數以千計的 bug。支撐 Swfit 開發和改進的團隊對于如何提升語言,以更好的支持那些使用 Swift 構建應用和系統的開發社區很感興趣。
Swift:更易上手,特性豐富的語言
從丟棄 Objective-C 賴以構建的傳統語言開始,一大堆變化讓 Swift 超越了 Objective-C。Apple 并沒有丟棄 Cocoa—— 這是他們的用于創建蘋果風格體驗的 API 和代碼庫——而是提供了一個完整功能的等價物,使得同支持 Force Touch 或者 Taptic Feedback 這類特性的新 API 交互起來更加簡單。
許多舊的設計決定都旨在讓編譯器的設計更加容易。Swift 則專注于通過拋棄傳統的緊張心理和編碼實踐,來使得應用開發者的工作更加輕松。隨著現代編譯器的發展,少量的代碼可以表示更多的信息。
使用 Swift,程序員只要維護原來一半量的代碼文件,手動的代碼同步工作為零,標點輸入出錯的概率也遠遠低于以前 -- 這樣就能騰出更多的時間寫高質量的代碼。通過使用可選類型 —— 一種針對返回或不返回值的編譯時安全機制,而返回值是同步操作、網絡失效時無效的用戶輸入以及數據驗證錯誤發生時普遍會遇到的問題。ARC 在 Swift 中對過程式 C 風格的代碼,還有蘋果公司 Cocoa 框架使用的面向對象代碼都進行了統一。
開發者會發現他們寫的 Swift 比較少,而現代的編程語言特性則支持著他們行行代碼都保持更多的可讀性。隨著其不斷發展,Swift 會保持整個蘋果公司的生態系統在編程領域的先進性,這都要感謝 iOS 和 Swift 中對動態庫的支持。開源項目、第三方 SDK 以及框架可以更容易的集成進家居自動化設備以及社交服務中,不會有編譯時間的增長。Swift 在某些算法的速度上幾乎與 C++ 一樣的快,而最新版的 Xcode 6.3 和 Swift 1.2 則在這一起跑線上把目標指向更多的性能優化。
再加上 playgrounds 和 swift 允許用一個新的方法來開發視覺反饋協助使用內聯數據可視化算法程序,讓一個較短的反饋回路和圖形描述迭代譯碼過程更容易開始。
最終,Swift 是一個平易近人的全功能的編程語言,未來將允許開發者不僅構建 app 還支持嵌入式系統比如新的低功耗 apple watch。