原創|使用教程|編輯:龔雪|2014-06-19 10:36:23.000|閱讀 1004 次
概述:初次接觸Swift總會有不少問題,比如剛入行的開發者應該學習Objective-C還是Swift?有沒有Swift可以實現,但Objective-C不能實現的事情?以及能否用Swift來調用自己的Objective-C代碼或者第三方庫等等。下面這篇文章針對這些問題進行了解答。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
作為蘋果在WWDC 2014上發布的新編程語言,Swift絕對是當前的熱門話題。Swift由蘋果開發者工具部門總監克里斯·拉特納(Chris Lattner)耗時四年開發而成,蘋果宣稱Swift的特點是:快速、現代、安全、互動,且全面優于Objective-C語言。
在Swift發布之后,隨之而來的便是各種入門教程,各種上手體驗,各種用Swift編寫的demo...不管是經驗豐富的開發者還是新手開發者都急切地想上手體驗下這門汲取了Objective-C、Rust、Haskell、Ruby、Python、C#以及CLU等編程語言精華的新語言。不過,初次接觸Swift總會有不少問題,比如剛入行的開發者應該學習Objective-C還是Swift?有沒有Swift可以實現,但Objective-C不能實現的事情?以及能否用Swift來調用自己的Objective-C代碼或者第三方庫等等。下面這篇文章針對這些問題進行了解答。
基礎部分
1、我是個剛入行的開發者,我應該學習Objective-C還是Swift,還是兩個都學?
這取決于你是計劃到其他公司工作,還是作為一個獨立iOS開發者。
a. 如果你是其他公司的全職iOS開發者或者顧問,你最好兩個都學。因為很多公司現有的代碼還是用Objective-C寫的,你需要理解這些代碼。并且一些公司不會立刻過渡到Swift語言開發。此外,你還需要理解使用Objective-C編寫的海量iOS庫、教程以及示例項目。另外,隨著時間的推移,很多公司會逐漸過渡到Swift開發,所以你也需要學習Swift。
b. 如果你是獨立開發者,你打算從一開始就使用Swift,理論上你只了解Swift就可以了。但如果你有時間,還是應該去了解Objective-C,這樣你就可以使用已有的Objective-C強大的資源庫。
根據市場的變化和Swift滲透率的增長,這個問題的答案也在不斷變化。最終,知道Objective-C可能會像知道COBOL一樣了。
2、我有多年的Objective-C開發經驗。對于Swift,我是新手么?
是,但也不是。如果你為蘋果平臺開發過一段時間,你仍有很大的優勢。因為你很熟悉Xcode和Cocoa/Cocoa Touch API。學習Xcode和上千個Cocoa/Cocoa Touch API要比學Swift花的時間更長,所以你有很好的開發基礎。長話短說,一旦你熟悉了Swift代碼,你就能很快地學習Swift。
3、iOS 8和OS X Yosemite的應用程序只使用Swift語言么?
不是。Swift語言能與Objective-C流暢地交互,反之亦然。蘋果并沒有完全將Objective-C 的API轉成Swift,但你仍可以在Swift代碼中仍使用這些API。時間會證明一切,但是很多年內iOS和OS X商店在采用Swift語言的同時仍會繼續依賴Objective-C語言。
4、Swift語言適用于其他版本的iOS和OS X系統么?
是的!Xcode 6可以為iOS 7及以上和OS X10.9及以上的系統版本編譯Swift代碼。其實,現在你從App Store下載的WWDC app就是蘋果用Swift語言編寫的。
但是,記住蘋果不允許使用Xcode Beta版本創建的應用程序提交到App Store。因此,你需要等到Xcode 6正式版發布才能在App Store中上傳Swift編寫的應用程序。
5、.Swift語言是取代Objective-C,還是對其的補充?
引用蘋果官方的一句話,“Objective-C不會消失,Swift和Objective-C可同時用于Cocoa和CocoaTouch開發。”因此,你仍然可以繼續使用Objective-C。然而,蘋果似乎鼓勵你使用Swift進行新的開發,而不是希望你重寫所有的Objective-C代碼。我們猜測蘋果在未來的框架和API開發中將會逐漸減少使用Objective-C語言,甚至有一天會棄用Objective-C,所以早作準備吧!
6、playground是什么?
playground是一個文件,你可以編寫代碼的同時即刻看到運行效果。對于學習Swift或者新的API、原型代碼或者算法真的很有用處!
7、如何學習Swift?
網上已經有很多不錯的資源:
蘋果的
你也可以在Xcode中閱讀本書:Help\Documentation and API Reference\New Features in Xcode 6 Beta\Swift Language\The Swift Programming Language\A Swift Tour\Open Playground)
我們的 和
8、未來你們的書和教程會使用Swift嗎?
會的。我們會幫開發者過渡到Swift。
進階
1、有沒有Swift可以實現,但Objective-C不能實現的事情?或者反過來說。
是的。Swift是一門現代語言,引入了很多Objective-C不支持的內容。比如命名空間(namspacing)、可選類型(optionals)、元組(tuples)、泛型(generics),類型推斷(type inference)以及其他等等。當然,Objective-C也有一些Swift不具備的特性,比如messaging nil.
想了解更多細節,建議在讀完本文后閱讀下蘋果的官方文檔: (這里有 )
2、有沒有Swift不能用的API?
在寫這篇文章時,我還沒發現有。但在使用Objective-C和Swift互通方面有些注意事項:
a. 當一個Objective-C的API返回一個id時,Swift將接收到AnyObject。
b. 當一個Objective-C API返回nil,Swift將獲得一組Optional類型的值,且被設置成NONE,Swift以這種方式來表示一個變量為nil。Swift的變量必須始終包含一個值,因為不能保證Objective-C 方法不會返回nil,所以Swift使用Optional類型枚舉來保存任何從Objective-C API返回的對象。
c. 當一個Objective-C API返回一個集合時,由于Swift無法判斷NSArray或NSDictionary存儲了什么類型,所以它會被轉換為AnyObject 。基于你對API的了解,向下轉換(downcast)你的集合是個很好的習慣。思考一個返回NSString實例的數組的Objective-C方法。由于你已經知道返回的數組里包含了字符串,所以你可以像下邊那樣安全地進行轉換:
let fruits : AnyObject[] = // some Objective-C API that returns NSArray of NSStrings for fruit in fruits as String[] { println(fruit) }
d. 當一個Swift API返回一個元組(Tuple),Objective-C將收不到任何值。這是因為Objective-C不支持元組,因此該方法不適用于Objective-C代碼。以下是Objective-C不支持的類型:
· 泛型(Generics)
· 元組(Tuples)
· 在Swift中定義的枚舉(Enumerations defined in Swift)
· 在Swift中定義的結構體(Structures defined in Swift)
· 在Swift中定義的頂級函數(Top-level functions defined in Swift)
· 在Swift中定義的全局變量(Global variables defined in Swift)
· 在Swift中定義的類型別名(Typealiases defined in Swift)
· Swift風格的variadics(Swift-style variadics)
· 嵌套類型(Nested types)
· Curried 函數(Curried functions)
3、Playground中,println()結果在哪里?
你必須打開Assistant Editor才能看到控制臺輸出。步驟:View > Assistant Editor > Show Assistant Editor,或者使用快捷鍵: Option + Command + Return.(感謝的這個觀點)
4、怎樣在Playgrounds中看到那些很酷的值的圖形?
你可以在Playgrounds里繪出值的結果,這對于可視化算法是很方便的。在playground里面輸入能夠產生值的代碼:
for x in 1..10 { x }
在側邊欄,你會看到類似于“9 times”的東西。把鼠標移到這一行上,會出現“+”按鈕。點擊這個按鈕(并確保你打開了Assistant Editor),你將會看到圖形。
5、你如何運行REPL?
在終端運行以下命令,告訴它使用Xcode 6的命令行工具。
sudo xcode-select -s /Applications/Xcode6-Beta.app/Contents/Developer/
然后運行以下代碼開始Swift REPL。
xcrun swift
如果準備退出,你可以鍵入:exit或者:quit。你也可以使用CTRL+D快捷鍵。
6.你能用Swift來調用自己的Objective-C代碼或者第三方庫嗎?如果能,要怎么做呢?
可以!當你往Xcode項目里添加第一個.swift文件時,系統會提示你讓Xcode創建一個橋接頭文件(bridging header file)。你可以在這個頭文件中導入你希望可見于Swift代碼的Objective-C頭文件。然后,所有的類無需導入都可為Swift所用,你可以使用和系統類相同的Swift語法來使用自定義Objective-C代碼。
7、那么,數組只能包含一個類型的對象嗎?如果我想要不同的類型呢?
在Swift中,強烈建議你使用只包含一種類型的強類型數組,語法像是:
var goodArray: String[] = [ "foo" , "bar" ]
也就是說,從技術上講,你依然可以創建包含多個類型對象的數組。但最好在做之前問問自己為什么想這么做。按照這種說法,你可以使用AnyObject:創建一個包含不同類型對象的Swift數組:
var brokenArray: AnyObject[] = [ "foo" , 1, 12.23, true ]
8、對于字典(dictionary)也是一樣嗎?字典也是強類型(strongly typed)的嗎?
是的,不過你依然可以用AnyObject來解決。對于字典來說,它里邊所有的值不是同一個類型也講得通。以下是用字典表示的從服務器端返回的一個JSON響應:
來看一個服務器JSON響應的例子,用字典來表示:
var employee : Dictionary<String, AnyObject> = [ "FirstName" : "Larry" , "LastName" : "Rodgers" , "Salary" : 65_000.00]
這個字典有兩個String類型的鍵和一個Double值類型的鍵。雖然這是可行的,但可能的話你應該創建一級類模型對象來表示數據,而不是依賴字典。
具體細節
1、在Swift中有id的等價替代嗎?
有。像上邊提到的那樣,當Objective-C API 返回id類型時,Swift使用AnyObject替換。AnyObject類型可以代表任何類類型的實例。另外也有Any可代表任何類型的實例(除了函數類型)。
2、如何在Swift中自省?(類似 if ([obj isKindOfClass:[Foo class]]) { … })
你可以使用is關鍵字檢查變量或者常量的類型。編譯器足夠聰明讓你知道使用is是多余的。由于Swift的類型安全機制,不大可能為同一個引用賦一個不同的類型。
var someValue : Any? someValue = "String" if someValue is String { println( "someValue is a String" ) } else { println( "someValue is something else" ) }
注意如果你想這么編寫的話...
var someValue = "String" if someValue is String { println( "someValue is a String" ) } else { println( "someValue is something else" ) }
你會收到一個編譯器警告:
Playground execution failed: error: <REPL>:7:14: error: 'is' test is always true if someValue is String {
3、如何在Swift的枚舉中存放位移值?(i.e. MyVal = 1<<5)
不幸的是蘋果尚未解決這個問題。不過有傳言稱他們正努力在這方面做的更好。按照這個說法,我們需要今天編寫代碼,對吧?以下是別人如何做到了這一點。
使用以下方案處理這個問題,你可以在 上查看更多細節:
struct MyOptions : RawOptionSet { var value: UInt = 0 init(_ value: UInt) { self.value = value } func toRaw() -> UInt { return self.value } func getLogicValue() -> Bool { return self.value != 0 } static func fromRaw(raw: UInt) -> MyOptions? { return MyOptions(raw) } static func fromMask(raw: UInt) -> MyOptions { return MyOptions(raw) } static var None: MyOptions { return MyOptions(0) } static var FirstOption: MyOptions { return MyOptions(1 << 0) } static var SecondOption: MyOptions { return MyOptions(1 << 1) } static var ThirdOption: MyOptions { return MyOptions(1 << 2) } } func == (lhs: MyOptions, rhs: MyOptions) -> Bool { return lhs.value == rhs.value } func | (lhs: MyOptions, rhs: MyOptions) -> MyOptions { return MyOptions(lhs.value | rhs.value) } func & (lhs: MyOptions, rhs: MyOptions) -> MyOptions { return MyOptions(lhs.value & rhs.value) } func ^ (lhs: MyOptions, rhs: MyOptions) -> MyOptions { return MyOptions(lhs.value ^ rhs.value) }
教程組成員 想到了下邊更簡單的方法,你可以在他的 里 閱讀更多內容。
class MyOptions { class var None : UInt32 { return 0 } class var All : UInt32 { return UInt32.max } class var First : UInt32 { return 1 } class var Second : UInt32 { return 1<<1 } class var Third : UInt32 { return 1<<2 } }
范例用法
physicsBody.categoryBitMask = MyOptions.First physcisBody.collisionBitMask = MyOptions.First | MyOptions.Second
Dave Lawson也寫了一篇你可能感興趣的文章:
以上是幾則相關的處理方法,不過希望蘋果在以后的版本中會解決這個問題。
4、Swift如何和Grand Central Dispatch一起使用?
同樣的方法,你可以像在Objective-C中那樣使用C API.在處理并發性時,你也可以使用蘋果高級NSOperationQueue。
5、Objective-C中的國際化宏命令呢?
類似Objective-C中的NSLocalizedString,你可以在Swift中使用NSLocalizedString(key:tableName:bundle:value:comment:) 方法為國際化做準備。tableName、bundle以及value arguments都有默認值,所以如果你正使用NSLocalizedString,你可以編寫如下代碼:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { println( "test" ) });
6、我需要擔心引用生命周期嗎?
當然!當兩個對象彼此之間是強引用時,仍能創建一個retain cycle。你可以使用Objective-C中一樣的方法break這個retain cycle。有三個關鍵字用于聲明引用類型,詳情如下,弱引用和無主引用將解決你的引用生命周期問題。
何時應該使用強引用、弱引用以及無主引用呢?
強引用:強引用會使得ARC保留實例直到不再需要它們。當移除所有強引用時,引用實例就會被釋放。注意默認情況下強引用是隱式的, 所以你不必顯式地聲明它。
弱引用:你應該在獨立生命周期的對象間使用弱引用。當為一個對象設置弱引用時,如果出于內存壓力釋放了對象,表示你不介意這一點。弱引用的值必須是一個變量,使用var定義 ,并且必須是使用?運算符的Optional類型。由于弱引用是可選的,所以你決不能以一個已經不存在的無效實例的引用來結束。當引用實例被釋放時,ARC將會自動把引用設 置為nil。
無主引用:你應該為有相同生命周期的對象使用無主引用;比如當一個對象指向其自身,以及你希望避免一個retain cycle。無論何時只要引用有一個值就可以使用無主引用,但當你需要告訴ARC不要將它設置為nil時。無主引用的行為類似于Objective-C的unsafe_unretained。你要確保你不會在引用對象被釋放后訪問引用,這樣會導致你的 app崩潰。無主引用不能是可選的,不能被設置為nil。無主引用也是隱式解析。
分號去哪里了?
分號在Swift中是可選的,不過出于易讀性的目的,蘋果建議你不要再使用分號了。但有時候仍會在Swift中使用分號,比如在循環語句中。
下一步做什么?
這僅僅是版本1,蘋果的目的非常清楚,他們將在該語言上進行迭代,所以你可以向蘋果報告bug,要求新特性等等。在該版本正式發布之前,仍有很大的提升空間。
CocoaPods如何適用于swift?
可能以類似的方式。Swift項目仍然是Xcode項目,并且支持多個target,但是有提升創建模塊和自定義框架能力的潛在空間。有可能會重新改寫CocoaPods以適應這個新特性。有人使用CocoaPods協助Swift項目工作,并且聰明的CocoaPods開發人員 。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn