首先要介紹的是 Bridging Header 這個檔案。
首先 產生一個 Single View Application 的專案。如下圖
這個就是新的 Xcode 6 產生專案的畫面,比之前 Xcode 5 少了幾個 (少了幾個呢?留給讀者去比較了)。
接著我們要選擇 Swift 這個語言。如下
命名為 SwiftObjc
然後我們要在專案的 Navigator 中新增一個 Objective-C 的 Class。如下。
記得要選的是 Cocoa Touch Class 而不是 Objective-C File 哦 。
命名為 Car。
記得 Language 是 Objective-C 哦。
接著不一樣的事情發生了。Xcode 會自動跳出一個提醒視窗。如下。
現在就先選擇 Yes 。來看看專案有什麼變化?如下
多了三個檔案哦。我們想要的 Car 這個 Class 的 .h, .m ,還有一個所謂的 Bridging Header 。在這的名稱為 SwiftObjC-Bridging-Header.h 。所以跳出視窗問的就是這個 Header,裡面長什麼樣子呢?基本上是空白。
因為我們要在 Swift Class 裡面用 Objective-C 的 Car class 。所以必需要加上如下的。程式碼。
就是 #import "Car.h" 。
也可以自已手動加,但需要改變專案的設定,如下圖
有一個 Objective-C Bridging Header 的設定要寫,記得除了寫 .h 檔名之外,還要加上 Product 名稱哦,通常就是 Project 名稱。
接下來我們就在 ViewController.swift 裡面使用 Car 這個 Class
如下
就可以直接在 viewDidLoad 裡面用 Car 這個 Class。而且用 Swift 語法
Car()在 Swift 中 Car() 就是和 Objective-C 的
[[Car alloc] init ]而且聰明的讀者有沒有發現到,在 Swift 裡面每個 row 的程式碼最後都不需要分號 ; 結尾
接著我們來加一下 method 在 Car 裡面。如下新增
Method 的名稱叫 setPrice:andYear: 這樣的 selector 要怎麼在 Swift 呼叫呢?Swift 也是支援 selector 的觀念,如下使用。
setPrice:andYear: 在 Swift 的語法就是
func setPrice( a:Int, andYear: b:Int)這也是 Swift 跳脫了傳統的 C function 的束縛加了一個新的語法叫 external parameter name 。也就是 andYear: ,在 Swift 的 function 裡用第二個參數的 external parameter name 來表示。
接著執行是會 Crash。為什麼?因為 Car.m 並沒有實作 -setPrice:andYear:。所以記得要實作。如下。
順便加上兩個 ivar,各是 price 和 year
這樣一來在 ViewController.swift 就可以執行成功。
對於 Selector 的觀念,我們再來做一個小小的實驗。
先在 ViewController.swift 再加上一些程式碼
我們要利用 NSTimer 來呼叫兩個 function 。分別是
func action(a:NSTimer, second b:Int ) {這個的 selector 寫成 Selector("action:second:")
println("action1")}
以及
func action(action a:NSTimer, second b:NSTimer){而這樣的寫法,無法對應到 Objective-C 觀念的 Selector
println("action2") }
執行後會發現一直出現 action1 的 log是正常的。
接著我們來看一下存取 ivar。在這個時候如果直接從 Swift 存取 Car 的 ivar 會發生如下錯誤。
放在 .m 的 ivar 應該是無法被看到,如果試著把 ivar 拿到 .h 來如下
結果也是一樣。在 Swift 要正常存取 Objective-C 的 ivar 。最好的方式就是利用 property,將 Car.h 改寫如下
再利用 Swift 來執行如下
就可以成功執行。
最後要來解釋一下 Objective-C 的 class method 要怎麼在 Swift 被使用。
我們要在 Car.h 加上 class method 如下
當然 .m 要對應好
怎麼在 Swift 中使用 +sharedInstance 呢?如下
var myCar = Car.sharedInstance()
這樣就可以了。看起來不難,不過提醒讀者名稱這事對於 Objective-C 和 Swift 都很重要,如果有一個 class method 命名成如下
+(instancetype) car;
在使用
var myCar = Car.car()就會造成 compiler 的錯誤,目前可以的話就盡量避免,直接用 Class 名稱第一個字小寫的 class method。
談了這麼多,到底應用在真實的例子是如何呢?
我們就拿 AFNetworking 的 framework 來測試。
這是一個非常有名也很多人用在網路的資料的傳輸上的 open source 的 framework。
在這就不簡介。先把 AFNetworking 的檔案都拉到專案
然後在 Bridging Header File 也要加上 AFNetworking.h 如下
最後補上一段,下載 Image 的程式碼就大功告成了啦
最後回答大家常問麥老師的問題,Swift 是不是非學不可?Swift 是不是會取代 Objective-C ?
Swift 是不是非學不可?
在這一二年內答案不是,但是因為 Swift 的好學好寫,我想再過不久 Swift 的 framework 不會比 Objective-C 少,到時,如果用到只有 Swift 版的 framework 就是非學不可了。Swift 是不是會取代 Objective-C ?
我個人是覺得再 5 年可能有機會,因為一個語言從出生到非常成熟可能需要 10 的年磨練,依照熱門程度不同,時間會有所調整,Swift 這麼火紅的情況下,可能會使它比較快穩定。我們可以看一個參考,如果 Apple 某個常用應用程式是用 Swift 重新改寫,完全取代 Objective-C 的日子就很近了。
以上一些,很久沒有寫文章的碎碎唸。希望大家有所收獲。請不吝指教。Michael 筆。
沒有留言:
張貼留言