成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

多鄰國團(tuán)隊的Swift代碼實踐

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

[[127033]]

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

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

首先,我們會簡單介紹一下這個新的應(yīng)用是做什么的和我們的主要目標(biāo)是什么。

新的應(yīng)用

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

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

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

目標(biāo)

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

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

對Swift的一般看法

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

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

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

優(yōu)點

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

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

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

沒有Exception

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

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

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

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

Optional

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

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

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

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

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

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

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

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

Result

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

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

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

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

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

Result是一個相當(dāng)優(yōu)雅的解決方案,它能讓你寫出更好、更簡潔、更安全的代碼。在我們的應(yīng)用中,任何可能執(zhí)行失敗(非致命的失敗)的表達(dá)式都會返回一個Optional或者Result。

和Objective-C的互操作

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

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

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

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

缺點

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

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

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

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

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

一些數(shù)字

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

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

崩潰

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

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

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

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

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

編譯器性能

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

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

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

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

結(jié)論

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

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

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

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

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

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

責(zé)任編輯:chenqingxiang 來源: cocoachina
相關(guān)推薦

2020-06-01 09:30:25

代碼開發(fā)Kotlin

2015-05-06 09:20:34

代碼質(zhì)量代碼審查實踐

2022-10-27 10:33:48

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

2017-09-13 16:46:38

敏捷站會團(tuán)隊

2018-07-05 13:35:04

DockerDevops開發(fā)

2016-08-11 14:02:02

NodeJS前端

2022-02-23 15:29:24

SwiftSwift 之父Chris

2024-05-21 07:54:30

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

2015-08-12 16:41:25

運維服務(wù)公共化

2020-06-11 10:22:04

遠(yuǎn)程工作CIO首席信息官

2022-02-20 22:16:44

ESLint工具JavaScript

2015-10-10 09:35:38

swift規(guī)范

2015-09-15 10:40:41

Swift2.0MVVM

2020-09-17 06:00:21

Git

2021-10-18 13:26:15

大數(shù)據(jù)數(shù)據(jù)分析技術(shù)

2018-04-24 09:00:00

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

2021-12-03 09:00:00

企業(yè)測試軟件

2025-03-20 08:25:24

2015-10-10 10:05:03

Swift2.0實踐

2021-10-09 11:54:46

DDD微服務(wù)業(yè)務(wù)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲精品性视频 | 国产乱精品一区二区三区 | 亚洲一区二区三区福利 | 91国产在线播放 | 久久久91精品国产一区二区三区 | 亚洲欧洲中文 | 亚洲国产91| 操久久 | 操久久久| 国产视频中文字幕 | www性色 | 久久精品国产一区二区电影 | 国产午夜精品一区二区三区四区 | 色婷婷综合久久久中字幕精品久久 | 一区二区三区四区视频 | 欧美日韩精品一区二区三区四区 | 国产精品色婷婷久久58 | 成在线人视频免费视频 | h视频在线免费 | 在线观看成年人视频 | а_天堂中文最新版地址 | 免费中文字幕日韩欧美 | 精品亚洲第一 | 美国一级片在线观看 | 精品国产免费人成在线观看 | 日韩一区欧美一区 | 综合久久99 | 69视频在线播放 | 日韩免费视频 | 国产午夜精品久久久 | 婷婷久久综合 | 日本欧美国产 | 国产色网 | 久久久久久免费精品一区二区三区 | www.99re5.com| 午夜专区 | 91久久精品国产91久久性色tv | 亚洲一区二区中文字幕 | 国产中文字幕在线观看 | 亚洲天堂成人在线视频 | 亚洲色图第一页 |