是時候用 Swift 了嗎?

jopen 8年前發布 | 19K 次閱讀 Swift

About the Speaker: Ben Sandofsky

Ben Sandofsky 平日的工作包括了制作應用、為創業公司提供建議,以及在 CodePath 上進行教學。他編寫軟件的經驗已經有十多年了,從小型創業公司到大型企業都有涉足。他在 推ter 中工作了 4 年,是 推ter iPhone、iPad 以及 Mac 端的技術領導。去年,他被硅谷的 HBO 聘用為技術顧問。

@sandofsky

</div>

如果您在一家小型企業的話,我在此所公開的相關標準,可能會幫助您加快開發進度;當然,我的意見對您可能并不適用,但是我希望總有一天它會對您有所幫助的。

這一幕似曾相識…(00:32)

今天,我們將要討論來自 Apple 強力推出的一個全新的、激動人心的運行時機制,能夠幫助開發者們使代碼運行速度更快、并且更安全。

1998 年引入的運行時: Steve Jobs 談論了 OS X 是如何通過使用這個令人激動的全新運行時機制,從而成為最好的操作系統的。他們保證這將是運行您 Java 應用的最快方式。

2008 年作為 Cocoa 開發的未來所引入的運行時:MacRuby。這是基于 LLVM 所研發的,通過無縫橋接的運行時機制給 Cocoa 開發帶來了現代化的最佳實踐。

現在,我們的問題來了:是時候用 Swift 了嗎?

是時候用 Swift 了嗎?(01:04)

Swift 已經到了所謂的“臨界點”。如果您看過 TIOBE 編程語言排行榜 的話,您會發現 Swift 已經超過了 Objective-C,僅僅次于 Pascal。 Ryan Olsen 從 App Store 中下載了最受歡迎的前 100 個應用,大家猜有多少使用了 Swift?11%!

不要輕信網上所言(02:54)

去年(2014)七月的時候,一些大公司的架構師明確表示,他們對 Swift 將保持觀望的態度。這消息的確令人有點沮喪。我為此列了一個 Tweetstorm,直到三個月后才有人來引用我。不過我建議,還是不要輕信網上的信息。您應當基于客觀、公正的分析,平衡風險和回報,再來做出您的決策。

最好的情況是怎樣的?(03:35)

有這樣一種新技術:代碼能夠實現自舉。 不過,并沒有人準確測量過,某種特定的語言要顯著比其他語言更有效率。在 多年以前的論文 當中,有人針對某個程序,使用了 80 種語言(C、C++、Perl、Python、Rex、TCL 等等)分別進行實現。確實,對于某個簡單的示例程序來說,輕量級的語言比那些重量級的語言(Java、C++、C)來說要快;這些輕量級語言在某方面確實很高效,占用的內存更低。

爭論語法是沒有意義的,三思而后行(04:48)

所有的腳本語言普適性并不強,它們只能針對某個平臺。而重量級語言就更進一步(因為它們不會隨意改變代碼的可維護性,因此我覺得 Python 比 Perl 要好用)。但是語法其實并不重要。Python、Ruby、Perl,它們所具備的生產力可能是相仿的。但是,生產力的主要決定權在于你,在于你的權衡過程。比如說你需要有一種具有 垃圾回收功能、內存管理很少的語言

因此,您決定是使用 Objective-C 還是使用 Swift 完全取決于您的需求,思路是相同的。您是否還想要自己管理引用計數呢(而不是使用 GC)?我該怎么使用 UIKit 呢? 我該怎么在 Core Animation 框架中卸載動畫呢(而不是使用計時器,每 60 毫秒觸發一次) ?語法發生了變化,但是您應用程序的整體復雜性其實是(大致)相同的。Swift 在提高您工作效率的層次上其實并沒有想象中的 并沒有那么高

您此前可能看到過: 某某公司重寫了某某語言的某某模塊,然后它們非常推薦大家使用這個新的模塊 !這里的關鍵是:他們已經重寫完了他們的應用,因此他們才有底氣說這種話。如果您重新回顧您寫過的每一款應用的話,這時候即使您已經知道了所有的業務需求,您要做的實際上還是編寫一個新應用,只不過需要更為精簡而已。的確,正如一位 Lyft 的工程師 所說:“如果我們決定重寫應用的話,我們實際上需要搭建一個全新的應用”。

總之,如果您試圖使用一個新語言重寫您的應用的話,這就會變成一個嚴肅的問題。保證您的新應用和老應用在功能上沒有任何的差異將是一個不小的挑戰。不過我認為,一次處理一個模塊,是最好的解決辦法。

讓我們來試一試:找出 BUG(07:26)

hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(&hashCtx)) != )
    goto fail;
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != )
    goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != )
    goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != )
    goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != )
    goto fail;
    goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != )
    goto fail;

Objective-C 的缺陷:C 是一個有缺陷的語言。如果您對黑科技有所了解的話(例如,switch 語句有用默認的 fallthrough 行為),你可以圍繞它做一些神奇的玩意兒。但是,Apple 并不能對 C 進行修改以讓其更為安全;因為它們必須要保證與 C 的向后兼容性。

@implementation NSString (Helper)
- (BOOL)containsString:(NSString *) string {
    NSRange range = [self rangeOfString:string options:NSCaseInsensitiveSearch];
    return range.location != NSNotFound;
}
@end

在 iOS 8 中,Foundation 中加入了一個名為 containsString: 的方法。有時我們需要讓 Foundation 中擁有不區分大小寫的字符串檢索功能,而系統提供的方法是區分大小寫的。使用 Objective-C 進行擴展的話,你需要給您的類別加上您公司的前綴才能使用。Swift 由于使用了命名空間,因此一般情況下,用 Swift 寫代碼更簡單、更安全、BUG 更少、更快捷,并且這些功能是內置在語言本身的。即使您只是簡單將 Swif 橋接到 Objective-C 當中,這些功能都可用。

最壞的情況又是怎樣的?(10:14)

1. 添加 Swift 支持將會增加包大小(10:21)

請一定要確保您支持 Bitcode 功能,還有確保最終打包的二進制包包含了 Bitcode (你必須要導出包,查看其中的某些文件夾以確保成功提供了支持)。

對于一個簡單的 Hello World 應用,Objective-C 版本的應用大小在 72K 到 92K 之間,而 Swift 版本的應用大小在 3.1M 到 4.6M 之間。不過這并不是一個大問題(例如,如果您的應用程序已經是 45M 大了,那么增加這么點額外空間并不是影響很大)。不過要記住,在那些發展中國家當中, 下載的成本是非常高的

2. 新規范意味著限制(11:52)

如果您更關注使用 Swift 的新規范的話,您可能會遭遇不少的限制。例如,使用 struct 來替代類,這是一個新的規范。當你想向其中引入 NSCoding 協議的時候,你會得到一個錯誤: non-class type 'Post' cannot conform to class protocol 'NSCoding’ (非類類型的 ‘Post’ 不能夠實現類協議 ‘NSCoding’)。我建議如果您打算使用 Swift 的話,放心大膽地使用結構體吧,不要害怕去使用你不清楚的東西(出錯了再改就好)。

3. 新的運行時意味著新的 BUG(13:18)

Mike Ash 發現了關于 弱引用的一個 BUG 。若引用有一個奇怪的條件,可能會觸發您應用的神秘崩潰。另外,我向一個內部的數據結構中傳遞了一些數據,但是實際上調試版本和發行版本的行為是不一樣的,最后導致其在啟動時崩潰了。

4. Swift 改變的太快了(14:23)

當然,語言的演變是好事,但是最終都會導致代碼的流失(code churn)。可汗學院有一個 30,000 代碼的應用。他們花費了一周時間將代碼遷移到新的 Swift 2 語法中。一個星期,你實際上可以向用戶提供更有價值的功能,而不是在改語法上。

Apple 的 Tyler Fox 承認,Swift 3.0 將會有重大的修改。我們知道,今年將會有更多的 Swift 的改變和變化,因此大家至少需要預算至少兩周的時間,浪費在新的 Swift 語法遷移和測試穩定性上。這就是演變所帶來的代價。

代碼流失使得重建依賴變得痛苦(15:17)

語言版本和 Xcode 版本捆綁在一起所帶來的副作用是,這會導致您掉入到依賴重建的坑當中。 當 DropBox 將它們的 2.0 SDK 換用 Swift 實現的時候 ,人們就不得不將他們的 Xcode 版本也換為最新的版本。因此,這會導致應用進入“維護”模式。比如說去年,我被硅谷的一家電視節目聘為了技術顧問,我寫了一個小小的應用,我使用的是 Swift 1.2,而現在由于我 Xcode 版本的限制。我不能隨意回滾回去,我必須要證明我將這個版本從 1.2 遷移到 2.0 所花費的一個星期沒有任何浪費。

遷移導致協調成本增高(17:07)

如果您在大公司工作(非死book、推ter),很可能團隊之間也是獨立工作的。您需要與您公司中的所有分團隊進行溝通協調。或者說,您的主應用中有兩個不同的團隊在負責(例如,一個團隊負責構建基礎框架和網絡協議棧,另一個團隊負責構建面向用戶的功能),您在協調共同上將會花費大量的時間和成本。

所以我的建議是什么?(17:56)

如果您在一個小團隊當中的話,由于協調成本很低,因此您完全不必被要花費兩周時間來遷移代碼這個消息給嚇壞, 直接上 就行。如果您對 Objective-C 很擅長,或者應用依賴很復雜,亦或者是忙不過來的話,那么我還是建議您 等待 Swift 3.0

Swift 3.0 之后,他們的重點將放在 ABI 穩定性上(您可以輕松地使用不用版本的 Swift 庫;它可能會嵌入到 iOS 系統當中,因此這可以減小您應用的大小)。在 Swift 3.0 中,看看 Foundation 和 UIKit 框架中將會有些什么新東西是一件很有意思的事情。我們非常期待框架的更新,這樣我們就可以擁有更多的經驗。他們將會深入到框架內部,嘗試用結構體、枚舉來替換那些遺留產物。你會發現有新的模式來取代 NSNotificationCenter 。隨著 Swift 3.0 的發布,我們都將擁有更合適的經驗。

謝謝大家!問題時間到!(20:00)

問:Apple 是不是計劃在未來的某一時刻,淘汰掉 Objective-C 呢?最近,某些庫當中所返回的數據類型是 Swift 的,而不是 Objective-C 的。您知道 Objective-C 會在什么時候被淘汰掉么?

Ben:( 我沒有在 Apple 工作,因此我可以暢所欲言 )關于此曾經有個采訪,Apple 的工作人員說他們很喜歡 OS X Carbon 中的 Objective-C API。我認為他們應該還是會繼續支持 Objective-C 的(雖然他們總是一直告訴開發者不要繼續使用了)。他們只是不贊成使用 Objective-C 而已,但是他們并不會將其移除。我認為為 Objective-C 應該會一直支持的。這些 API 應該會一直存在,直到 Objective-C 跟不上時代的發展,沒有任何使用意義的時候,才可能會被拋棄。這就是為什么我覺得太過關心不贊成的 API 是毫無意義的,我對此完全沒有任何壓力。

問:希望這美好的想法不會被打破!

Ben:這個問題實際上 iOS 也有。我曾聽說過一個傳聞:Apple 是那種,東西一旦建好,就再也不會改它,這種類型的公司,因為它已經可以用了!OS X 仍然還有 Carbon 的蹤影,因為 Carbon 仍然可以用。如果他們拋棄了 Objective-C,那么 iOS 應該是首當其沖的。Apple 最重要的目的是向后兼容,因此這么做很可能會損害他們維護的 UIKit 的向后兼容性。因此,我一點也不擔心 Objective-C 會被拋棄。

問:有沒有某種切實可行的方法,能夠將 Objective-C 應用一塊塊地轉換為 Swift,而不是重寫呢?

Ben:我認為他們在 Swift 中做的最美妙,也是最聰明的事情是:你可以混編 Objective-C 和 Swift,這樣你可以一個文件文件的來修改。如果有人拿著一款運行良好、完美的 MVC 機構的應用來找我,我會說:先把現有的代碼放一邊,剩余的新工作用 Swift 就可以了,確保注釋完善、橋接配置良好即可。如果代碼可以正常工作的話,那么最重要的部分就是提出一個完善的過渡計劃了。你應該強硬地認定:“從這里開始,除非有特殊的理由,否則你都應該全部使用 Swift 來寫應用”。

例如,我曾經在許多應用中看到不同的解決方法,某個大團隊中的一些開發者決定摒棄原有的單元測試風格的 TDD 開發方式,轉用行為驅動開發。他們開始了將他們的測試遷移到 BDD 框架中(不過由于他們并沒有太多時間,到現在這項工作還未完成)。最糟糕的狀況是新的開發者當中,一部分寫的是 Objective-C,而另一部分寫的是 Swift,他們沒有明確的方向。這對構建系統的資源安排來說是非常不好的,并且在使用 BDD 系統的情況下,當他們開始搭建持續集成服務器的時候,所有的管理員都必須要搭建兩套不同的服務器,以便解析兩種不同的報告,這會導致事倍功半。因此,重要的是您需要有一個遷移計劃,說明從現在開始我們只能使用 Swift,不能夠浪費時間回歸到 Objective-C 中去尋求代碼整潔。

問:我在一個擁有龐大 Objective-C 代碼庫的項目中工作,我覺得現在還不是遷移到 Swift 的好時機。不過有一件事我開始做的就是,當我創建新的類的時候,我都確保我的所有指針都使用了 nonnull 以及 nullable 關鍵字。這是不是一個好的策略呢,可以幫助最后徹底遷移到 Swift?

Ben:當然,Swift 代表的是未來,就像你的代碼開始看起來像 C++ 一樣。如果我只是獨自一人,為自己的應用工作的話,那么我可以隨意放棄舊的代碼,不過一般而言我會懶得這么做。但是,如果你準備看向未來的話,那么我可以保證現在是一個里程碑。

問:您此前提到可從 Objective-C 遷移到 Swift 的計劃,是否還有其他看起來與之類似的遷移計劃呢?就是您是否在其他團隊,或者其他應用,或者整個組織當中,看到他們成功完成了遷移呢?回顧 35 年的軟件開發歷史,是否還有其他的相關例子呢。這種遷移已經不是第一次發生了。誰做的最好,誰做的最差呢?

Ben:這可能有點超出我的知識范圍了,不過我覺得從 Carbon 遷移到 OS X 應該是一個不錯的例子。還有幾年前,從手動管理引用計數 (MRC) 過渡到自動引用計數 (ARC)。我堅持觀望一段時間后再遷移到 ARC 當中,但是我們團隊中有一個強烈的意愿表示:“我們在 Apple 中就用著這個了,它能夠減少崩潰。”這不是讓一個特定的工程師回去,改變所有權模式(在一個房間里面花費幾周時間,然后一點點修改以讓其能夠運行)就好了的。我們需要一個平滑的遷移操作,因此我們一個文件一個文件的來,并且這種特殊的所有權模式中的特定元素確實非常煩人,我們就只讓這個文件脫離 MRC 即可,而不是浪費一個星期來調試以讓其完美運行。

不幸的是,我能想到最接近的例子就是當工程師們選擇了一個非 Apple 的 iOS 框架的時候,一旦框架發生改變,它們就需要從頭開始重寫。這非常痛苦。我會說最好的辦法就是進行規劃,一點一點來,并且不能夠喪失激情。如果您打算進行完全的重寫的話,那么要改變的不是語言,而是架構,你要將通用的 MVC 換用為公司中更深層次的結構。在我進行 iOS 開發之前,我曾經遇到過一次重寫任務,我們將最好的開發者們放在一個房間里寫了好幾個月,他們對應用進行了完全的重構。但是當他們開始加入更多的開發者之后,由于代碼審查的缺失,導致了相同的問題(架構混亂),這就導致了惡性循環的產生,這是我們應該要避免的。

問:關于開發新應用我有個問題:您是否會直接使用 Swift 進行開發呢?我指的是一個全新的應用,一切都是從頭開始的那種。

Ben:對我來說,那么肯定就是一個選擇:使用 Swift!這樣很棒,一旦有朝一日這款應用火爆起來之后,也就是 Swift 3.0 出來之后,我或許會將它賣給 非死book,我覺得可以賣個一百萬美元。我曾經和友人討論過這個,對他們來說 SDK 是戰略的重要組成部分,他們覺得 使用 Swift 弊大于利 。一旦您開始涉及到為公司和投資者負責這一個高度上面的話,我傾向于保守態度;我想讓事情變得簡單一點,平滑一點,不對他人造成傷害,因為他們給我們公司錢,他們才是上帝。

問:Swift 中使用 NSNotification 會出現問題?

Ben:是的。 NSNotificationCenter 需要 NSObject 或者其引用類型:你沒法對 Swift 值類型建立觀察。我不是說通知不是一個好的 API,我是說為了實現 Swift 值類型的觀察,我需要想出一個新的方法來實現。我想說這讓我有點心煩。我們非得需要構建自己的通知么,比如說,構建一個注冊中心以替代 NSNotificationCenter 么?一旦你開始涉足一個不熟悉的領域,那么你的實際進度就會變得非常非常緩慢,效率低下。但是我沒有想到,因為雖然我知道這個特定模式基本是百分百成功的,但是一旦我改變行為方向,那么這個模式就沒法工作了……這是一個惡性循環,因此我不得不重塑這些對我來說需要死記硬背的代碼。

問:您剛才已經提出了一個關于新產品和新公司的想法了:通知中心的替代品。我覺得您可以成為下一個 Realm。

Ben:借您吉言,希望如此吧!

See the discussion on Hacker News .

Get new videos & tutorials — we won’t email you for any other reason, ever.

來自: https://realm.io/cn/news/ben-sandofsky-time-for-swift/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!