歡迎加入QQ討論群258996829
贏了現(xiàn)在輸了未來(lái) 頭像
蘋(píng)果2袋
2
贏了現(xiàn)在輸了未來(lái)

詳解Swift 2.0(一):蘋(píng)果做的25項(xiàng)改變

發(fā)布時(shí)間:2015-07-24 19:13  回復(fù):0  查看:4195   最后回復(fù):2015-07-24 19:13  

毫無(wú)疑問(wèn),Swift 2.0在2015全球開(kāi)發(fā)者大會(huì)(Worldwide Developers Conference, WWDC 2015)上被發(fā)布的消息眾人皆知。我會(huì)就該語(yǔ)言所發(fā)生的變化撰寫(xiě)一系列的文章,但目前我們先說(shuō)說(shuō)重點(diǎn)。

常規(guī)變化


  • 現(xiàn)在全局函數(shù)和獨(dú)立(free-standing)函數(shù)都和方法一樣,遵循同一個(gè)參數(shù)標(biāo)簽規(guī)則。不再使用#這樣的語(yǔ)法來(lái)引用外部資源。
  • 你基本上可以使用enum SomeEnum<T,U,V>來(lái)聲明multi-payload風(fēng)格的枚舉,這樣就能正常運(yùn)行。這用來(lái)提示未完成的指令寄存器(IR)引發(fā)的錯(cuò)誤。
  • 條件循環(huán)語(yǔ)句目前的語(yǔ)法是repeat { } while(cond),不再使用do。
  • 關(guān)鍵字do目前用來(lái)引入一個(gè)新的作用域(這對(duì)新引進(jìn)的錯(cuò)誤處理和 defer 關(guān)鍵字很重要)。在 C 語(yǔ)言中你可以用大括號(hào),但 Swift 里就要理解為閉包(closure)。所以使用關(guān)鍵字do可以任意引入作用域。
  • guard語(yǔ)句塊顯式地聲明你要恒成立的條件語(yǔ)句,恒成立時(shí)跳過(guò)整個(gè)guard 語(yǔ)句。這樣做的好處是綁定在guard語(yǔ)句的變量在函數(shù)的其他部分也可用。這就避免了將所有的東西都圍繞一條if語(yǔ)句嵌套使用來(lái)解析(unwrap)可選類(lèi)型的變量。執(zhí)行到函數(shù)中g(shù)uard語(yǔ)句中的else部分,函數(shù)一定會(huì)退出并拋出異常。也可能會(huì)調(diào)用帶有@noreturn標(biāo)記的函數(shù)。
  • 文本注釋?zhuān)╠oc comments)換成了Markdown格式,與Playgrounds統(tǒng)一(Playgrounds注釋格式源于功能有限的reStructured Text)。
  • 編譯器對(duì)冗余的協(xié)議一致性,未被使用的綁定值以及可以設(shè)為常量的變量這些情況目前會(huì)給予警告或報(bào)錯(cuò)。
  • Swift語(yǔ)言的調(diào)用約定更加智能,能夠理解 API 所發(fā)生的變化和 Swift 所給出的警告。并且還可以升級(jí)(但還不是那么完美,一定還漏掉了一些東西)。
  • find函數(shù)改名為indexOf,sort則變成了sortInPlace,sorted變成了sort。
  • String不再直接遵循序列類(lèi)型(SequenceType),大概是為了避免一些新的可用協(xié)議擴(kuò)展。目的是迫使你使用s.characters,s.utf8或s.utf16明確你想處理的unicode編碼。
  • 允許對(duì)泛型添加公共擴(kuò)展。
  • 非泛型類(lèi)類(lèi)型可以繼承泛型類(lèi)(強(qiáng)制類(lèi)型參數(shù)固定)。
  • 便利的可失敗構(gòu)造器(failable initializer)可以先返回nil,而不必首先調(diào)用self.init。這是有利的一面,但指定了構(gòu)造器在返回nil前仍要給所有字段初始化。所以此處還有改進(jìn)的余地。


內(nèi)部的可見(jiàn)性

這解決了單元測(cè)試中的一個(gè)較大的難點(diǎn)。以前的做法:


  • Swift文件包含在test target中?,F(xiàn)在不同的模塊中有重復(fù)的類(lèi)的定義,出現(xiàn)無(wú)法將“X”轉(zhuǎn)換為“X”這樣非??膳碌腻e(cuò)誤,有時(shí)會(huì)無(wú)法執(zhí)行特定的測(cè)試。
  • 在測(cè)試中引入引入主程序(main program)作為一個(gè)模塊?,F(xiàn)在一切都聲明為public,所以對(duì)于測(cè)試來(lái)說(shuō)都是可見(jiàn)的,有時(shí)候也包括應(yīng)該聲明為private的內(nèi)部細(xì)節(jié)。


現(xiàn)在可以啟用testability,它就像C#中的InternalsVisibleTo。主應(yīng)用程序目標(biāo)模塊的內(nèi)部細(xì)節(jié)對(duì)測(cè)試模塊可見(jiàn)。


  • 在對(duì)應(yīng)用或框架的測(cè)試設(shè)置中,啟用testability。
  • 在單元測(cè)試中,使用@testable import {ModuleName}。


這將導(dǎo)致測(cè)試忽略某些優(yōu)化行為并保留稍后導(dǎo)入到測(cè)試模塊中的那些內(nèi)部符號(hào)。官方文檔警告說(shuō),由于阻止了某些優(yōu)化,因此這只適用于調(diào)試和測(cè)試版本。

模式匹配

switch語(yǔ)句的模式匹配(pattern matching)語(yǔ)法和“if let ..., .... where”語(yǔ)法一直在推廣。可以在任何控制流中使用逗號(hào)操作符和where條件語(yǔ)句。還可以使用新的case條件語(yǔ)句,例如:if case .Silly(let a) { }。還有一種用于Optional<T>的特殊形式:if case let a? = anOptional { }。

模式匹配在循環(huán)語(yǔ)句中也可以使用:for case let thing? in array { }。

這又是值得單獨(dú)成文的另一個(gè)特性。

Objective-C的泛型和__kindof的用法

在關(guān)于Swift的文章里談?wù)撨@個(gè)做甚?它的作用是使某些銜接更加清晰和簡(jiǎn)便。不求在這篇文章中面面俱到,我會(huì)再單起一篇文章闡述它。

錯(cuò)誤處理

這不是我們一貫所認(rèn)識(shí)的異常,這是一個(gè)使函數(shù)提前返回Result<T, Error>的操作,單隱藏了所有提前返回的對(duì)象,也隱藏了錯(cuò)誤解析(error unwrapping)過(guò)程等內(nèi)容。


let systemAttributes: [NSObject: AnyObject]?
do {
    systemAttributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last!)
} catch _ {
    systemAttributes = nil
}

它完美地與Objective-C進(jìn)行互操作,Swift語(yǔ)言中,將標(biāo)記為throws的方法作為選擇器。這是使用NSError的方法,-(BOOL or nullable type)someMethodTakingParam:(type)param error:(NSError **),這種樣式會(huì)自動(dòng)引入標(biāo)記為throws的方法。

應(yīng)該明白的是這并不像Java中已經(jīng)被檢查過(guò)的異常(checked exception)那樣。Swift語(yǔ)言并不關(guān)心異常的類(lèi)型,或者處理或者不處理。這又是值得單獨(dú)成文的另一功能特性。

Defer關(guān)鍵字

關(guān)鍵字defer也很重要,因?yàn)樗梢匀〈鷤鹘y(tǒng)C風(fēng)格的“if(err) goto cleanup”。獲得資源后接著就是defer { release_resource() }。然后不管函數(shù)返回結(jié)果如何,獲得的資源都將被清理。這也意味著資源的釋放緊隨獲取資源之后。這看起來(lái)不起眼兒,實(shí)則很重要。

NS_OPTIONS和OptionSetType

位操作枚舉(bitwise enumeration)與數(shù)組風(fēng)格的語(yǔ)法相結(jié)合,而不使用管道符“ | ”按位操作,并且具有所有范圍的集合操作功能。檢查一下是否具有contains功能的標(biāo)志,或能夠執(zhí)行像isSubsetOf和isDisjointWith等這樣集合操作的其他功能。這是顯著的改進(jìn),表達(dá)了不直接對(duì)位進(jìn)行操作的意愿。

這種變化意味著位操作枚舉實(shí)際上不再是枚舉了。將這些位操作枚舉聲明為結(jié)構(gòu)體,實(shí)現(xiàn)OptionSetType協(xié)議,提供rawValue屬性。并且創(chuàng)建值作為結(jié)構(gòu)體的靜態(tài)成員。Swift便會(huì)搞定其余的一切,自動(dòng)提供所有集合的操作。這是我希望將來(lái)看到的更加明了的語(yǔ)法內(nèi)容。

協(xié)議擴(kuò)展

協(xié)議如今可以被擴(kuò)展了,包括與類(lèi)型約束有關(guān)的通用協(xié)議。還可以自己提供協(xié)議的默認(rèn)實(shí)現(xiàn)。

先前,你不能你說(shuō):“我要使用方法X來(lái)擴(kuò)展CollectionType,但只有集合中的類(lèi)型滿足某些條件才可以”?,F(xiàn)在,你可以這么做,并且很多像map,filter和sort這樣的全局函數(shù)已經(jīng)進(jìn)行了擴(kuò)展。

這樣就解決了很多痛點(diǎn),這也是值得單獨(dú)成文的內(nèi)容。同時(shí),要看看WWDC的面向協(xié)議編程(Protocol Oriented Programming)了解一些細(xì)節(jié)。

API審計(jì)

大量的API已經(jīng)進(jìn)一步進(jìn)行了審計(jì)而更合理。舉幾個(gè)例子:


  • UITableView的dequeueReusableCellWithIdentifier方法現(xiàn)在返回UITableViewCell?類(lèi)型的對(duì)象。
  • UIKit的屬性現(xiàn)在也被聲明為了實(shí)際的屬性。


用translatesAutoresizingMaskToConstraints = false代替了setTranslatesAutoresizingMaskToConstrains(false)。

Availability屬性

@available屬性自Swift 1.2就存在了并且后續(xù)支持得很好。添加了一個(gè)新的陌生語(yǔ)法if#available(),為處理版本檢查提供了支持。而不是插入你喜歡的方法。

遺憾的是你不能只聲明一個(gè)屬性UISearchController并將target設(shè)置為iOS 7,然后只允許訪問(wèn)類(lèi)中的屬性。Swift希望整個(gè)類(lèi)的定義都可以或者不可以。

也可以不再采用協(xié)議,除非支持target設(shè)置中所有的操作系統(tǒng)版本,除非將整個(gè)類(lèi)標(biāo)記為只在更新的操作系統(tǒng)版本可用。

這意味著使用if #available()存在單獨(dú)的子類(lèi)和對(duì)創(chuàng)建適當(dāng)對(duì)象的保護(hù)。

盡管如此,我個(gè)人還是發(fā)現(xiàn)了一個(gè)Bug,應(yīng)用在iOS 4.0-4.1發(fā)生崩潰,由于編譯器沒(méi)有發(fā)出警告,方法只在iOS4.2才引入,因此我猶如與定時(shí)炸彈相伴。

C函數(shù)指針

Swift現(xiàn)在可以使用C函數(shù)指針,CFunctionPointer已不復(fù)存在。任何全局函數(shù),嵌套函數(shù)和不捕獲狀態(tài)的閉包都可以作為一個(gè)C函數(shù)指針直接傳遞。你也可以調(diào)用來(lái)自C程序的函數(shù)。

你可以顯示地使用新屬性@convention(c),表示函數(shù)應(yīng)該使用C調(diào)用約定,簡(jiǎn)單痛快!盡管我想不出在此對(duì)塊(block)的支持有何用,作為所發(fā)生變化的一部分,@objc_block也被刪掉了,使用@convention(block)取而代之。@convention(swift)默認(rèn)支持所有函數(shù)和閉包。

庫(kù)

這并不是編程語(yǔ)言所特有的。iOS 9含有不同版本的Swift標(biāo)準(zhǔn)庫(kù),并且在未來(lái)系統(tǒng)中將添加修正后的Swift標(biāo)準(zhǔn)庫(kù)。結(jié)合新的App Thining技術(shù),下載過(guò)程中蘋(píng)果商店會(huì)將Swift標(biāo)準(zhǔn)庫(kù)剝離出去的。我仍然在追根溯源地探求這究竟是如何工作的。

遺漏

明顯的一個(gè)遺漏是處理異步代碼。

蘋(píng)果公司為我們提供了GCD,這是一個(gè)強(qiáng)大的基礎(chǔ)類(lèi)庫(kù),可以構(gòu)建很多異步操作和并發(fā)原語(yǔ)。

然而,這些天我們做的每件事,構(gòu)建用戶接口和API都需要考慮異步性和并發(fā)性。我們把一個(gè)文件讀操作鎖定一段時(shí)間,對(duì)用戶來(lái)說(shuō)整個(gè)世界就都靜止了。

這是個(gè)持續(xù)的痛點(diǎn),不是多大的事兒,但如果經(jīng)常性地每天重復(fù),恐怕也是不行的。

C#和JavaScript都采用了async/await來(lái)為異步代碼提供一流的語(yǔ)言支持。我想很多人都想知道,Swift會(huì)提供什么樣的語(yǔ)法糖來(lái)幫助我們?cè)趯?shí)現(xiàn)異步操作方面確保正確性。我不知道在Swift 2.0發(fā)布的時(shí)間框架內(nèi)是否會(huì)看到什么,但愿能有好的東西出現(xiàn)吧!

開(kāi)放源碼

宣布的內(nèi)容中,反響最強(qiáng)烈的無(wú)疑是Swift開(kāi)放源代碼。蘋(píng)果公司已經(jīng)承諾在今年底前開(kāi)放源碼,我們也沒(méi)有理由對(duì)此表示懷疑。與蘋(píng)果公司編譯器團(tuán)隊(duì)成員討論過(guò)程中,他們看起來(lái)似乎對(duì)此由衷地興奮,無(wú)論如何堅(jiān)決要干成這件事(我有點(diǎn)小失望,他們沒(méi)有打造出經(jīng)典的蘋(píng)果然后宣布開(kāi)源,但我仍然對(duì)此消息發(fā)自?xún)?nèi)心地感到高興)。

結(jié)論

Swift 2.0有很多令人喜愛(ài)之處。蘋(píng)果公司的Swift團(tuán)隊(duì)向大家承諾他們會(huì)迅速行動(dòng)。到目前為止這些承諾已經(jīng)被兌現(xiàn)。成為蘋(píng)果平臺(tái)上的開(kāi)發(fā)人員是一個(gè)激動(dòng)人心的時(shí)刻。

(翻譯/白云鵬 友情審校/汪洋)

文章來(lái)源Russ Bishop's Blog

作者簡(jiǎn)介:Russ Bishop,全能型程序員,使用C#、Objective-C和Swift語(yǔ)言編程,開(kāi)發(fā)了奇特的應(yīng)用Storm Sim Free。

譯者簡(jiǎn)介:白云鵬,移動(dòng)應(yīng)用開(kāi)發(fā)者,個(gè)人博客:http://baiyunpeng.com


您還未登錄,請(qǐng)先登錄

熱門(mén)帖子

最新帖子

?