包含3節(jié)視頻教程
關(guān)注9.7萬次
學(xué)習(xí)FumeFX制作煙霧、火焰的教程可以讓你操作火煙。甚至制作水墨的效果!這些強大的技術(shù)可以讓特效看起來很棒!掌握后你將變成特效大師!
如果你還不知道Swift的話,你應(yīng)該回頭復(fù)習(xí)一下蘋果的WWDC 2014發(fā)布會了。WWDC 2014上蘋果出人意料地宣布了一種從Objective-C進化而來的全新語言——Swift,這在我所知的蘋果發(fā)布會歷史上,還是頭一遭介紹這么一個外人摸不著頭腦的東西。好在是WWDC,臺下坐著的基本都是開發(fā)者,從基調(diào)演講的現(xiàn)場反應(yīng)來看,大家對Swift的反響是出乎意料的強。另一方面,從今年WWDC的會議日程來看,除去幾乎每天都有“動手做環(huán)節(jié)“——Swift Lab之外,光是含Swift字樣的講座就不下8個。有面向小白的“Introduction to Swift”,面向中級者的“Intermediate Swift”,還有上級者向的“Advanced Swift Debugging in LLDB”、“Swift Interoperability In Depth”等。這不,已經(jīng)有公司發(fā)出招聘啟事:招聘Swift開發(fā)人員,要求Swift編程經(jīng)驗不少于1天。一時間似乎全世界都在討論Swift。
蘋果還火上澆油,在《The Swift Programming Language》里開門見山地宣稱[1]
Swift融合了最佳的現(xiàn)代編程語言思想和最強力的蘋果工程學(xué)文化。Swift語言在優(yōu)化開發(fā)流程的同時,卻沒有在性能上進行任何妥協(xié)。
先來看看普通類型和容器好了。字符串處理的好壞,決定了一個現(xiàn)代語言的第一印象。在這里我們看到Swift做的似乎還不錯,列表容器的定義和使用也和諸多現(xiàn)代語言接近,在這一點上讓開發(fā)者對Swift平添了不少好感。
// let關(guān)鍵字做常量定義 let famouseDeveloper = "Hideo Kojima" // var關(guān)鍵字創(chuàng)建變量,下面是一個列表容器 var bigHandPublishers = ["EA", "Activision", "Tencent"] bigHandPublishers[2] = "UBI Soft" //有點丟人還是換了吧 for publisher in bigHandPublishers { // 字符串格式化 println("\(famouseDeveloper) once worked at \(publisher).") } // 認(rèn)真你就輸了 // Hideo Kojima once worked at EA // Hideo Kojima once worked at Activision // Hideo Kojima once worked at UBI Soft現(xiàn)代語言大抵會把函數(shù)和閉包作為第一公民處理,即享受基本類型的同等待遇,有些情況下待遇甚至更高。Swift也不例外。在閉包的使用上,由于拋棄了Objective-C里繁瑣的語法,不再是block那種張牙舞爪的樣子,變成了下面的小清新狀:
// 函數(shù)定義 func foobar() { println("Hello World") } // 帶返回值定義的函數(shù) func httpResponse() -> (Int, String) { return (200, "Succeeded") // 支持多重返回值 } /* * 帶閉包參數(shù)的函數(shù) * 注意task參數(shù)聲明為一個不帶任何參數(shù)和返回值的閉包 */ func repeat(count: Int, task: () -> ()) { for i in 0..count // 注意這里的range,是[0, count) { task() } } // 如何調(diào)用看下面 repeat(2) { println("Hello World!") } // 打印結(jié)果: // Hello World! // Hello World!Swift是一門類型安全的語言,它支持duck typing,但還是嚴(yán)肅地對待類型,編譯期間會做類型檢查。這對于使用動態(tài)語言的粗心程序員來說無疑是一種福利。于是像這樣,Swift可以聲明變量的類型:
var i:Int = 30
也可以聲明optional類型,也就是在類型后面加問號:
var optionalInteger: Int?
Optional value看似稍有點麻煩,但帶來了更多的安全性,相信也是蘋果在設(shè)計這門語言中做出的取舍。Optional的概念還帶來了所謂的optional chaining,用更少的判斷來鼓勵更少的錯誤。以發(fā)布會的例子來說
//這是原Objective-C的寫法 if (myDelegate != nil) { if ([myDelegate respondsToSelector: @selector(scrollViewDidScroll:)]) { [myDelegate scrollViewDidScroll:myScrollView]; } } // 這是Swift的寫法 myDelegate?.scrollViewDidScroll?(myScrollView)對上面的例子可以這么理解:當(dāng)optional value為nil的時候,運行時(runtime)不進行unwrap,并且直接跳過后續(xù)表達(dá)式的計算。是不是碉堡了?
可能你會說Swift像某某語言。沒錯,一千個人眼里有一千個哈姆雷特,Python程序員覺得Swift像Python,Ruby程序員覺得像Ruby,還有人覺得Swift像是拿Go改的一版Objective-C。這正是蘋果棋高一著的地方,在讓你感受新語言的簡潔高效之外,還不讓你覺得它太陌生,順便還能向你的朋友們炫耀一下你的博學(xué)多才。
據(jù)說,現(xiàn)在github上Swift語言的開源項目已多達(dá)300多個了,而我們卻沒有太多時間關(guān)心這當(dāng)下最火的語言。給我們一點時間,下次來聊一聊對Swift的一些更深刻的認(rèn)識與不滿,這樣也對得起標(biāo)題里的“不”字。主題不僅僅限于:Objective-C的包袱、蘋果的封閉平臺、繼承和擴展、對象生命周期管理。
Swift很討巧,給人以一種簡潔、有力的第一觀感?粗渌』锇橐呀(jīng)一日千里地奔著Swift去了,你已經(jīng)躍躍欲試了?別急,今天來給大家降降溫。須知硬幣都有正反面,Swift在給予開發(fā)者便利的同時,也精心準(zhǔn)備了諸多深坑供大家玩耍。
~我們已經(jīng)可以扔掉Objective-C了么?~
Swift以帶問號的語法引入了optional類型,主責(zé)是將未初始化變量以一種主動的形式迫使開發(fā)者知曉。而開發(fā)者若想使用optional,即“允許未初始化”的變量時,必須使用感嘆號來進行取值,也就是所謂的unwrap。
var illegalString :String = nil // 編譯錯誤 var legalString :String? = nil func genString(bar :Int) -> String? { if bar > 30 { return "abc" } else { // 如果可以返回nil,必須強制返回類型為optional return nil } } var a: String = genString(50)! // 必須進行取值操作,否則類型不匹配 var b: String? = genString(0)蘋果在設(shè)計Swift的時候,將安全擺在了一個相當(dāng)重度的位置,從而犧牲了語言的隨性。寄希望于Swift能更像腳本語言那樣隨意編寫的同學(xué),可能會在optional這里感受到來自語言設(shè)計者的惡意。
這個問題還算比較良性。我們通常寫帶參數(shù)的函數(shù)是這樣
//這樣很好,與世無爭 func foobar(a: Int, b: String) -> String {...}但是,皇上您還記得大明湖畔的夏雨荷么?
- (instancetype)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding多么令人懷念的老時光。Swift為了要兼容Objective-C/Cocoa,也搞出了類似的東西,稱之為“外部參數(shù)名”:
class Matrix { func doMultiplication(str :String, fromData data1 :Int[], withData data2: Int[]) { // do something } } let m = Matrix() m.doMultiplication("My Matrix", fromData:[1,1,0,1], withData:[1,1,2,3])從第二個參數(shù)開始,每個參數(shù)還有內(nèi)外兩個名字?這種丑到爆的語法真是歷(nan)史(yi)沉(tu)疴(cao)啊╮(╯▽╰)╭
毫無意外地,Swift是一門(帶少量函數(shù)式編程特性的)面向?qū)ο笳Z言。同樣毫無意外地,Swift類必須安裝有初始化函數(shù)init。秉承前面optional帶來的安全理念,開發(fā)者對于init的編寫也有諸多規(guī)定,也就演化出了特定初始化函數(shù)和便利初始化函數(shù),以及隨之而來的convenience關(guān)鍵字。
class Item { let name :String init(givenName name:String) { self.name = name } } var item = Item(givenName: "GeneralItem") class Grenade : Item { let explosive :Int init(givenName name: String, withExplosive explosive: Int) { self.explosive = explosive // 必須在子類初始化完畢所有成員后,再調(diào)用 // 基類的構(gòu)造;否則編譯錯 super.init(givenName: name) } convenience init(explosive: Int) { // 所謂的便利構(gòu)造函數(shù)只能調(diào)用子類的特定構(gòu)造函數(shù), // 并不能涉及到基類構(gòu)造;否則編譯錯 self.init(givenName:"MyGrenade", withExplosive:explosive) } } let grenade1 = Grenade(givenName: "MyGrenade", withExplosive: 500) let grenade2 = Grenade(explosive: 300)寫個初始化函數(shù)這么麻煩?為了安全,就得這么麻煩!其實不只是初始化,為了安全,連簡單的switch結(jié)構(gòu)也必須寫default,這安全與好用的功與過,就全憑使用者來評判了。
蘋果從Objective-C時代就引入了輔助對象生命期管理的自動引用計數(shù)(ARC)機制。Swift也一并繼承了ARC。雖然ARC有輕量化、行為可預(yù)測、沒有垃圾回收機制卡頓的優(yōu)勢,但也帶來了很要命的問題:無法自行解決循環(huán)引用問題——從而引起內(nèi)存泄露。
內(nèi)存泄露難以跟蹤、忽隱忽現(xiàn)又破壞力極大,它無疑是程序員最恐怖的夢魘。無奈之下,Swift引入了兩個關(guān)鍵字weak和unowned,修飾不會自動增加引用計數(shù)的變量,來解決循環(huán)引用問題。
class Person { let name: String var buff: Buff? init(name: String) { self.name = name } } // 施加在人物身上的buff技能 class Buff { let id: Int weak var target: Person? init(id: Int) { self.id = id } } var me = Person(name: "Jon Blow") var buff = Buff(id: 42) me.buff = buff然而游戲中buff是跟著人走的。沒有人就談不上buff,這就意味著Buff類中target設(shè)置為optional是不合適的。更好的做法是使用unowned。
class Person { let name: String var buff: BetterBuff? init(name: String) { self.name = name } } class BetterBuff { let id: Int unowned let target: Person init(id: Int, withTarget target: Person) { self.id = id self.target = target } } var me = Person(name: "Jon Blow") me.buff = BetterBuff(id: 42, withTarget:me)這里友情提醒一句,解決普通對象之間的循環(huán)引用只是戰(zhàn)斗的開始。Swift是門現(xiàn)代語言,函數(shù)和閉包都是一等公民,所以后面還有閉包之間的循環(huán)引用等著勇敢的程序員們。
另外還有一些語言特性看上去新奇,但基本上只能算是Objective-C的翻版,例如protocol和extension,基本上是復(fù)制了Objective-C的protocol和category,并沒有為解放程序員的雙手帶來更多好消息。 值得一提的倒是外圍特性:Playgrounds。Playgrounds并不是Swift語言自帶的功能,而是Xcode 6中一種新工程形態(tài)。如果不是發(fā)布會上那驚鴻一瞥,Playgrounds恐怕會湮沒在眾多新特性的海洋之中。Playgrounds是促進蘋果整個生態(tài)系統(tǒng)的一個巨大進步,它為Swift配置了動態(tài)語言的專利——交互式環(huán)境。而且還像matlab這類軟件一樣,Playgrounds提供數(shù)值視覺化效果,這類難能可貴的“所見即所得”,讓游戲的細(xì)調(diào)的工作變得如捏橡皮泥搬簡單。雖然Playgrounds之后會否發(fā)展成為一個單獨的編輯器,我們不得而知,但Swift+Playgrounds+Sprite Kit毫無疑問已經(jīng)向Corona這類二線游戲引擎產(chǎn)生了致命的沖擊——一個飛速發(fā)展的生態(tài)圈內(nèi),是容不下弱者的。
說起來,Xcode 6 beta中的Playgrounds還非常地不穩(wěn)定,沒有足夠的勇氣不要輕易嘗試哦~
講了這么多Swift的壞話,回過頭來我們還是要認(rèn)真評估一下它的未來:盡管Swift有著這樣那樣的妥協(xié)、不足,但它仍將是2014年增長速度最快的語言,沒有之一,就像沉默十幾年的Objective-C在iPhone開發(fā)熱潮興起之時,一瞬間成為了世界的寵兒。且不說,Swift所依賴的開源編譯系統(tǒng)LLVM,也是目前編譯器界最受矚目的項目。他的創(chuàng)造者Chris Lattener,也就是那個WWDC上演示Playgrounds的默默無聞的天才少年,已經(jīng)多次被ACM協(xié)會授予編譯器、語言、系統(tǒng)方面的獎項。他在編譯器、語言生態(tài)系統(tǒng)的遠(yuǎn)見卓識,讓LLVM在原先強大的業(yè)界標(biāo)準(zhǔn)——GCC編譯系統(tǒng)面前迅速崛起。不用猜,目前我們Xcode使用的編譯系統(tǒng)正是LLVM。
行文至此,我們可以初步得出結(jié)論:Swift是一門脫胎自O(shè)bjective-C的語言,帶有濃厚的Objective-C/Cocoa的痕跡,也遵循了前輩的一些設(shè)計哲學(xué),但同時擁有強大的現(xiàn)代語言特性。在權(quán)衡了易用性和安全性的前提下,做到了一定的動態(tài)語言的功能——不能說是盡善盡美。它的底層由強大且開放的LLVM支撐,外圍又有Xcode所帶來的Playgrounds讓開發(fā)者立即上手。憑借蘋果的開發(fā)生態(tài)圈,Swift必將以極快的速度取代Objective-C成為蘋果平臺開發(fā)的首選。至于Swift是否有望擴展到其他平臺,WWDC并沒有給予我們答案。參考蘋果之前的作風(fēng),恐怕其底層庫Cocoa移植的可能性不大。但由于LLVM的存在,Swift以開源編譯器的形態(tài),舍棄Cocoa而出現(xiàn)在各家平臺上的可能性還是很大的。
朱峰社區(qū)網(wǎng)頁版(手機掃描-分享-添加到屏幕)
朱峰社區(qū)微信公眾號(微信掃一掃-關(guān)注)
未知用戶
2005-2025 朱峰社區(qū) 版權(quán)所有 遼ICP備2021001865號-1
2005-2025 ZhuFeng Community All Rights Reserved
VIP