自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

多鄰國團隊的Swift代碼實踐

移動開發(fā) iOS
最近我們剛剛發(fā)布了一款新的基于Swift的應用,當時還被蘋果著重推薦了,目前它已經獲得了相當多的用戶。在這片文章里,我們想要分享一下這些經驗,把我們對于這個新語言的看法呈現(xiàn)給大家,并且指出Swift中那些可以讓我們寫出更好程序的新特性。

[[127033]]

最近我們剛剛發(fā)布了一款新的基于Swift的應用,當時還被蘋果著重推薦了,目前它已經獲得了相當多的用戶。在這片文章里,我們想要分享一下這些經驗,把我們對于這個新語言的看法呈現(xiàn)給大家,并且指出Swift中那些可以讓我們寫出更好程序的新特性。

這不是一篇Swift入門指南,這篇文章的受眾是那些對Swift并不是很熟悉,而且好奇Swift在真實的編程過程中是怎么樣子的開發(fā)者。我們會引用一些技術概念并且會在合適的地方提供關于它們的入門指南和文檔的鏈接。

首先,我們會簡單介紹一下這個新的應用是做什么的和我們的主要目標是什么。

新的應用

你可能已經很熟悉我們的主應用Duolingo,一個非常受歡迎的語言學習應用,它擁有超過6000萬的用戶(截止2014年12月),它也曾被蘋果評為2013年年度應用。如果你想要學習一門新的語言,Duolinggo將是你在你的iPhone或者iPad上的首選應用。

之后,我們發(fā)布了Duolingo Test Center(下文稱Test Center),這個應用非常實用,它可以讓你測試你對一門語言的掌握情況。例如,如果你是一個外國人,并且想要在美國或者英國的大學里尋求一份工作,這些工作通常都會要求你有一些官方證書,來證明你可以熟練使用英語。此應用的用戶可以通過一些測試來讓用戶確定自己的語言水平,同時為了防止作弊,會有真人來監(jiān)督測試。

這款應用發(fā)布伊始就被蘋果在超過50個國家的APP Store“最佳新應用”中推薦。

目標

性能方面,Test Center對性能要求并不高。應用中大部分都是一些靜態(tài)內容和少量的控件。另外,為了防止作弊,測試的全過程會被錄像,基本Test Center就是這樣了。我們在使用Swift的過程中并沒有碰到任何性能問題,但是還是必須要注意一下性能。

對我們來說更重要的是應用的穩(wěn)定性和健壯性。由于測試會持續(xù)大約20分鐘并且它們是收費的,所以在測試途中崩潰會造成相當差的用戶體驗1。另外,一旦一個測試開始,你就必須完成它(就是說,用戶不能暫?;蛲顺龃藨茫贿@樣做是為了防止作弊)。所以,我們需要將崩潰的可能性最小化。

對Swift的一般看法

當Swift剛發(fā)布時,許多人只是看了看它的語法就開始拿它和其它語言作比較、下結論。有些人說他們現(xiàn)在“不再需要忍受Objective-C的語法”,可以直接開始iOS開發(fā)了。老實說,這種看法是錯誤的。誰會在意語法(只要語法不是很變態(tài))?對于一門語言來說,除了語法還有很多更重要的東西,比如它可以讓你更容易地表達你的想法,還有不鼓勵不好的行為。

Swift比Objective-C或者任何其它語言都能給我們帶來更多的啟發(fā)。如果你在Twitter上關注了Swift的一些作者,你就會知道他們從其它地方拿來了很多非常好的概念,包括函數(shù)式編程,同時他們也在合適的地方摒棄了很多現(xiàn)存的(但是并不十分理想)的概念。

由于我們已經習慣了用Objective-C 來編程,Swift對我們來說是一個不錯的的且友好的進步。如果你本來用的語言是Haskell(或者similar),你可能會覺得Swift仍有進步的空間。同時我們也很期待未來的Swift版本會帶來什么更多的改進。

優(yōu)點

Swift支持了很多新特性,這些特性是開發(fā)者在其它語言的使用過程中已經習慣了的,像是自定義操作符和函數(shù)重載。值類型(含有字面上的值的類型,例如Swift的結構體)可以讓你更容易的理解代碼。

我們也非常喜歡使用Swift中更強大的靜態(tài)類型系統(tǒng),還有類型推斷。尤其是當Objective-C中沒有泛型時,在Swift中我們終于有了類型安全的集合,而不是只能希望在NSArray中存儲的是某一種類型的對象。

接下來詳細得看一下我們在Swift中發(fā)現(xiàn)的十分實用的特性

沒有Exception

到現(xiàn)在為止,Swift中還沒有錯誤處理。我們并不知道是Swift的作者在設計這門語言時特意不加入錯誤處理,或者只是因為當時時間不夠。不論如何,我們覺得沒有錯誤處理是一件非常好的事情,因為(沒有被處理的)exception讓代碼更難被讀懂(被良好處理的exception能讓代碼變得更清晰,讓開發(fā)者知道在哪里會發(fā)生exception,但是它們又顯得過于笨重了,反正Objective-C中就不支持exception處理)。

事實上,在我們最常碰到的應用崩潰的原因中,第七個就是因為蘋果提供的一個方法拋出了exception(-[AVAssetWriterInputHelper markAsFinished])。這個方法并沒有被標記為會拋出exception,在文檔中也沒有注明,所以在真正看到這個崩潰報告之前,我們完全不知道它的行為會是這樣,而那時有些用戶的應用已經崩潰了。

有經驗的Cocoa開發(fā)者會知道,盡管Objective-C提供exception拋出和處理的機制,但它只在極少數(shù)情況下使用,而且這些情況經常是一些不可恢復的情況(盡管有一些例子)。在這種情況下,更好的解決方案可能不是去獲取并處理這個exception,而是去改善代碼,使得這個exception根本不會被拋出。有些人可能會爭論說這樣exception好像變成是一個失敗斷言方法,但可能這個概念本來的設計目的就是這樣呢,那么在一個含有assert()和fatalError()的新語言中,為什么還要保留它呢?

通常,我們都想要避免自己忘記去處理一個錯誤,更理想的情況,我們想要在編譯時就發(fā)現(xiàn)所有的問題,而不是在我們的應用已經崩潰之后。Exception 只會讓這變得困難,所有我們在Swift中為什么還需要使用它呢?

Optional

Swift中有很多非常重要的基本概念,Optional(你可能知道這個和Haskell中的Maybe類型很像)便是其中之一。蘋果的文檔中這么寫道:

Optional是一個有兩個值的枚舉類型,None和Some(T),它們分別代表無值和有值。所有類型都可顯式地(或者隱式地轉換為)一個Optional類型。

同時,Swift提供了簡單方便的使用Optional類型的語法糖,例如在None的情況下可以使用nil,特殊的展開語法,操作符等等。另外,Optional鏈還允許你寫出簡單清晰的包含多Optional依賴的代碼。

那么我們怎么使用它呢?Optional是一個非常好的用來表示“值可能為空”的方法,你可以用它作為函數(shù)的返回值類型,來表示這個函數(shù)可能會不返回任何結果(只要你不好奇這究竟是為什么)

為什么這會比在Objective-C中給一個指針賦值為空更好呢?因為這樣編譯器(在編譯期)就能保證我們操作的是正確的類型。換句話說,在Swift中一個不是Optional類型的值永遠不可能為空,另外,由于Swift中的Optional不僅僅是簡單的指針類型,所以他們的用處更廣泛。

這里是一個關于Optional使用的小例子:在Objective-C里,所有返回直指針類型的方法,比如對象初始化方法(例如-init),都可能會合法的返回nil(例如當一個對象不能被初始化)。一個很明顯的例子就是+ (UIImage *)imageNamed:(NSString *)name,只通過看這個方法名,你并不能確定它會不會返回nil。

然而在Swift里你就可以。蘋果在Swift中引入了可失敗的初始化程序的概念,這樣就可以很方便地在類型的層面上表達一個方法不會返回nil。在Swift里,同樣的例子是這樣子的: init?(named name: String) -> UIImage,注意這里有個問號,這個問號表示如果標識符為name的變量找不到時,init方法可能會返回nil。

我們在合適的地方大量的使用了這個特性(我們在試圖避免對Optional進行顯式的拆包或者強制拆包)。如果一個表達式可能會返回nil(例如失敗時)而且我們不需要知道為什么,那么Optional便是很好的選擇。

Result

如果你有一個可能會失敗的函數(shù)調用,而且你想要知道為什么它會失敗,那么你可以使用Swift提供的Result(對于函數(shù)式編程的開發(fā)者而言,他就像Either的子類型),它會是一個既簡單又實用的選擇。

和Optional相似,Result使你可以在類型的層面上表示一個東西可能是一種類型的某個值,或者是一個NSError

像Optional一樣,Result也是一個簡單的枚舉類型,它有兩個枚舉值Success(T)和Failure(NSError)。正常情況下success枚舉值會包含你感興趣的正常的值,如果有錯誤,你會得到一個.Failure和一個描述性的NSError。

和Optional不同的是,Result不是Swift標準庫的一部分,也就是說,你必須自己定義它。(當前階段,編譯器還缺少一些相關的特性,你需要找到一個變通方案。)

我們在我們的網絡通信、I/O、和代碼分析模塊的很多地方都用到了Result,這個方案要比老的NSError指針在函數(shù)里傳入傳出,或者通過一個completion塊來包含成功的值和錯誤指針(或者更復雜的布爾型返回值和NSError指針的一起使用的方案)要好太多了,

Result是一個相當優(yōu)雅的解決方案,它能讓你寫出更好、更簡潔、更安全的代碼。在我們的應用中,任何可能執(zhí)行失?。ǚ侵旅氖。┑谋磉_式都會返回一個Optional或者Result。

和Objective-C的互操作

與Objective-C的互操作是Swift設計時的一個很重要的考慮因素。如果蘋果僅僅是發(fā)布一個新的編程語言,然后想用Swift的實現(xiàn)完全代替之前的所有代碼庫是行不通的——至少現(xiàn)在還不行。另外,開發(fā)社區(qū)里還有大量的Objective-C的代碼,如果沒有與Objective-C不錯的互操作性,可能不會有人愿意去用Swift。

幸運的是,Swift和Objective-C之間的互操作相當簡單,而且我們已經在一個很小的范圍里進行了一些實踐,效果還是不錯的。但是值得注意的是,有些Swift的概念(比如枚舉)在Objective-C中并不能直接使用。

例如,我們的應用中有一個小的功能部件需要操作PDF文件,這個部件我們是用Swift來寫的,然后我們又想在主應用中使用這個模塊,主應用是用Objective-C寫的。哎,偏偏有一些方法使用了僅Swift中才有的特性,這就意味著這些方法不能在Objective-C中不能自動被橋接。為什么繞過這個問題,我們簡單地對Swift的方法做了一個包裝方法,這個方法可以在Objective-C中使用2。

當然,在Swift中直接使用我們主應用中已有的Objective-C代碼也是非常簡單的。如果想要這么做,你只要簡單地把那部分代碼從應用中拿出來(或者更好,它本身就是一個單獨的模塊),然后通過一個橋接頭文件導入你的Swift代碼中。

缺點

盡管Swift相比Objective-C而言有了很多進步,但是現(xiàn)在它還是有一些地方需要改進的。例如,這門新語言缺少一些其他現(xiàn)代語言中常見的高可表達性。但是作為一個新的語言,可能這種情況會很快改變。

蘋果保障說會保證兼容性,但是還說他們可能會在合適的時候修改這門語言的一些特性(實際上,他們已經這樣做過幾次了)。這就意味著在更新編譯器之后你可能必須去修改你的代碼,否則就不能編譯通過。我們知道這種事情會發(fā)生,并且也無所謂,幸運的是,對于我們現(xiàn)存的之前運行良好的代碼,“修復”它們往往不需要花太多的時間。

我們對Swift最不爽的——也是我們受挫的根源——可能并不是語言本身,而是與之配套的工具。在Xcode(蘋果的Objective-C和Swift的IDE)上使用Swift的體驗還不是很好。在我們開發(fā)的過程中,Xcode經常會運行很卡或者直接崩潰。大部分時間里并沒有(或者很慢)代碼提示,基本上可以說沒有調試器,不穩(wěn)定而且不可信的語法高亮,編輯器很慢(一旦項目達到了一定的大小),還有沒有重構工具。

另外,編譯器報的錯誤信息經常難以理解,編譯器中也還有一些bug和缺失的特性(例如類型推斷經常出錯)。

從我們開始使用到現(xiàn)在,Xcode已經有了很大的進步了,大部分都很好,只是有一些小地方破壞了編程體驗。我們希望蘋果能多一些關注并且不斷改進這個開發(fā)工具。

一些數(shù)字

蘋果是在2014年6月的WWDC大會上發(fā)布Swift的,同年的7月底,我們啟動了Test Center,它是我們第一個只用Swift語言開發(fā)的應用,之后我們在十一月中旬發(fā)布了它。開發(fā)到1.0版本耗費了3個月多一點的時間(一個程序員;Android版本和web版本那時已經存在了,所以當時我們確實已經有了完整的后臺和設計)。

像我們之前說的,健壯性和穩(wěn)定性對我們而言非常重要,所以讓我們在這方面是怎么做的。

崩潰

在寫這篇文章時,Test Center已經發(fā)布有大約兩個半月了,并且已經有了相當大的下載量和用戶量(可能要歸功于被蘋果推薦的原因)。

和其他任何第一版一樣,我們碰到了很多之前沒碰到過的問題,但是幸運的是,我們似乎并沒有忽略任何很重要的bug。到今天為止,test center的崩潰率在大約0.2%,好像還不錯嘛3。

如果仔細看一下崩潰組(由于同樣的原因造成的崩潰):崩潰組的第一名(造成了大約30%的崩潰)是由于外部的Objective-C庫。事實上,前五名中有四組是由于Objective-C的原因造成的(第五名是由于一個我們在最終的發(fā)布版本中忘了關掉的失敗斷言)。

還有一個值得注意的是,第七名是因為前面提到的那個蘋果提供的Objective-C函數(shù)中有時會拋出exception,而這點在文檔中并沒有體現(xiàn)(-[AVAssetWriterInputHelper markAsFinished])。

我們把這么低的崩潰率歸功于可靠的軟件架構和我們對一些很好的編程原則的堅持,然而,Swift的優(yōu)良的設計也減低了很多bug產生的可能性,這對我們去構建我們的軟件架構是很有幫助的。例如,使用Swift的類型系統(tǒng),很多的錯誤可以在編譯期被發(fā)現(xiàn),而不是在已發(fā)布產品運行時才被發(fā)現(xiàn)4。

編譯器性能

我們必須要問一個問題,對于一個像我們這種規(guī)模的項目,編譯器是怎么來編譯的。根據(jù)sloc的數(shù)據(jù),我們的項目中現(xiàn)在有10634行實際代碼(不包含空行和注釋等)。

清除Xcode的緩存,然后運行完time xcodebuild -configuration Release命令需要2分鐘,一次調試運行需要大約30秒的編譯時間。所有的測試都是在一個mid 2013 Retina MacBook Pro上做的。需要注意的是編譯xib也需要一定的時間,并不全是Swift5。

你可以明顯的感覺到Xcode會隨著你的項目的增長變得越來越慢,而且碰到這個問題的不僅僅是我們。循環(huán)時間(當你在改動了代碼之后,從按下CMD+R,到應用在模擬器里打開的時間)也比Objective-C要長。在一次簡單的測試中,在代碼中增加一行,要等14秒編譯,這個時間取決于在這行代碼中到底做了什么,而在Objective-C的項目中作相似的改動,只需要2、3秒。

當然,這并不是復雜的編譯器基準測試,所以可以有保留的看待這些數(shù)字。希望你至少能對現(xiàn)在的編譯器性能有一個大致的了解。

結論

對于Objective-C的長期開發(fā)者來說——尤其是那些對現(xiàn)代編程語言感興趣的——Swift是一個受歡迎的且激動人心的進步,同時,由于(當前的)開發(fā)工具的原因,它有時也可能會讓人倍感挫折。

我們已經展示了(至少在我們這類的應用中)Swift可以用來寫出穩(wěn)定的健壯的并且高容量的應用。我們的主應用Duolingo,也已經使用了一部分Swift代碼,我們也計劃在將來更多的使用它。

那么為什么你會選擇Swift呢?只要你在開發(fā)大型項目時有保持更新的用戶(你只能支持iOS7以上)和耐心,Swift提供了一個新鮮的,良好結構的編程語言選擇。我們真誠地推薦你試一下它,特別地,去理解一下蘋果想要推廣的這種編程哲學。

如果你正在使用Objective-C,那么轉換到Swift還是比較簡單并且直接的。你可以用和Objective-C一樣的編程方法來使用Swift。當你使用到一些Swift中新的概念時,會很有趣。尤其現(xiàn)在好像有一種擁抱函數(shù)式編程的趨勢,我們認為這挺好的。

如果你已經有了一個基于Objective-C的應用,你可能不想為了使用Swift而完全重寫整個應用,但是你在增加模塊時可以考慮用Swift來實現(xiàn)。

如果時光倒流,你必須要重寫這個應用,你還會用Swift嗎?會。

責任編輯:chenqingxiang 來源: cocoachina
相關推薦

2020-06-01 09:30:25

代碼開發(fā)Kotlin

2015-05-06 09:20:34

代碼質量代碼審查實踐

2022-10-27 10:33:48

敏捷開發(fā)開發(fā)

2017-09-13 16:46:38

敏捷站會團隊

2022-02-23 15:29:24

SwiftSwift 之父Chris

2018-07-05 13:35:04

DockerDevops開發(fā)

2016-08-11 14:02:02

NodeJS前端

2015-10-10 09:35:38

swift規(guī)范

2024-05-21 07:54:30

視頻多模態(tài)語義檢索算法

2020-06-11 10:22:04

遠程工作CIO首席信息官

2022-02-20 22:16:44

ESLint工具JavaScript

2015-09-15 10:40:41

Swift2.0MVVM

2015-08-12 16:41:25

運維服務公共化

2015-10-10 10:05:03

Swift2.0實踐

2025-03-20 08:25:24

2021-12-03 09:00:00

企業(yè)測試軟件

2022-12-02 09:02:36

Swift代碼異步

2020-09-17 06:00:21

Git

2018-04-24 09:00:00

開發(fā)自動化軟件架構

2021-10-18 13:26:15

大數(shù)據(jù)數(shù)據(jù)分析技術
點贊
收藏

51CTO技術棧公眾號