互用性(互通性)使開發人員可以定義融合了 Objective-C 語言特性的Swift類。編寫 Swift 類時,不僅可以繼承 Objective-C 語言編寫的父類,採用 Objective-C 的協議,還可以利用 Objective-C 的一些其它功能。這意味著,開發人員可以基於 Objective-C 中已有的熟悉、可靠的類、方法和架構來建立 Swift 類,並結合 Swift 提供的現代化和更有效語言特點對其進行最佳化。
繼承Objective-C的類
在 Swift 中,開發人員可以定義一個子類,該子類繼承自使用 Objective-C 編寫的類。建立該子類的方法是,在 Swift 的類名後面加上一個冒號(:),冒號後面跟上 Objective-C 的類名。
複製代碼 代碼如下:
// SWIFT
import UIKit
class MySwiftViewController: UIViewController {
// 定義類
}
開發人員能夠從 Objective-C 的父類中繼承所有的功能。如果開發人員要覆蓋父類中的方法,不要忘記使用override關鍵字。
採用協議
在 Swift 中,開發人員可以採用 Objective-C 中定義好的協議。和 Swift 協議一樣,所有 Objective-C 協議都寫在一個用逗號隔開的列表中,跟在所在類的父類名後面(如果它有父類的話)。
複製代碼 代碼如下:
// SWIFT
class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// 定義類
}
Objective-C 協議與 Swift 協議使用上是一致的。如果開發人員想在 Swift 代碼中引用 UITableViewDelegate協議,可以直接使用UITableViewDelegate(跟在 Objective-C 中引用id<UITableViewDelegate\>是等價的)。
編寫構造器和析構器
Swift 的編譯器確保在初始化時,構造器不允許類裡有任何未初始化的屬性,這樣做能夠增加代碼的安全性和可預測性。另外,與 Objective-C 語言不同,Swift 不提供單獨的記憶體配置方法供開發人員調用。當你使用原生的 Swift 初始化方法時(即使是和 Objective-C 類協作),Swift 會將 Objective-C 的初始化方法轉換為 Swift 的初始化方法。關於如何?開發人員自訂構造器的更多資訊,請查看構造器。
當開發人員希望在類被釋放前,執行額外的清理工作時,需要執行一個析構過程來代替dealloc方法。在執行個體被釋放前,Swift 會自動調用析構器來執行析構過程。Swift 調用完子類的析構器後,會自動調用父類的析構器。當開發人員使用 Objective-C 類或者是繼承自 Objective-C 類的 Swift 類時,Swift 也會自動為開發人員調用這個類的父類裡的dealloc方法。關於如何?開發人員自訂析構器的更多資訊,請查看析構器。
整合Interface Builder
Swift 編譯器包含一些屬性,使得開發人員的 Swift 類整合了 Interface Builder 裡的一些特色功能。和 Objective-C 裡一樣,你能在 Swift 裡面使用 OutLets,actions 和即時渲染(live rendering)。
使用Outlets和Action
使用 Outlets 和 Action 可以串連原始碼和 Interface Builder 的 UI 對象。在Swift裡面使用 Outlets 和 Action,需要在屬性和方法聲明前插入@IBOutlet或者@IBAction關鍵字。聲明一個 Outlet集合約樣是用@IBOutlet屬性,即為類型指定一個數組。
當開發人員在 Swift 裡面聲明了一個 Outlet 時,Swift 編譯器會自動將該類型轉換為弱(weak)、隱式(implicitly)、未封裝(unwrapped)的 optional(Object-c裡面對應指標類型)資料類型,並為它分配一個初始化的空值nil。實際上,編譯器使用@IBOutlet weak var name: Type! = nil來代替 @IBOutlet var name: Type。編譯器將該類型轉換成了弱(weak)、隱式(implicitly)、未封裝(unwrapped)的 optional 類型,因此開發人員就不需要在構造器中為該類型分配一個初始值了。當開發人員從故事板(storyboard)或者xib檔案裡面初始化對象 class 後,定義好的 Outlet 和這些對象串連在一起了,所以,這些 Outlet 是隱式的,未封裝的。由於建立的 outlets 一般都是弱關係,因此預設 outlets 是弱類型。
例如,下面的 Swift 代碼聲明了一個擁有 Outlet、Outlets 集合和 Action 的類:
複製代碼 代碼如下:
// SWIFT
class MyViewController: UIViewController {
@IBOutlet var button: UIButton
@IBOutlet var textFields: UITextField[]
@IBAction func buttonTapped(AnyObject) {
println("button tapped!")
}
}
在buttonTapped方法中,訊息寄件者的資訊沒有被使用,因此可以省略該方法的參數名。
即時渲染(live rendering)
開發人員可以在Interface Builder中用@IBDesignable和@IBInspectable來建立生動、可互動的自訂視圖(view)。開發人員繼承UIView或者NSView來自訂一個視圖(view)時,可以在類聲明前添加@IBDesignable屬性。當你在 Interface Builder 裡添加了自訂的視圖後(在監視器面板的自訂視圖類中進行設定),Interface Builder 將在畫布上渲染你自訂的視圖。
注意:只能針對架構裡對象進行即時渲染
你也可以將@IBInspectable屬性添加到和使用者定義的運行時屬性相容的類型屬性裡。這樣,當開發人員將自訂的視圖添加到 Interface Builder 裡後,就可以在監視器面板中編輯這些屬性。
複製代碼 代碼如下:
// SWIFT
@IBDesignable
class MyCustomView: UIView {
@IBInspectable var textColor: UIColor
@IBInspectable var iconHeight: CGFloat
/* ... */
}
指明屬性特性
在 Objective-C 中,屬性通常都有一組特性(Attributes)說明來指明該屬性的一些附加資訊。在 Swift 中,開發人員可以通過不同的方法來指明屬性的這些特性。
強型別和弱類型
Swift 裡屬性預設都是強型別的。使用weak關鍵字修飾一個屬性,能指明其Object Storage Service時是一個弱引用。該關鍵字僅能修飾 optional 物件類型。更多的資訊,請查閱特性。
讀/寫和唯讀
在 Swift 中,沒有readwrite和readonly特性。當聲明一個儲存型屬性時,使用let修飾其為唯讀;使用var修飾其為可讀/寫。當聲明一個計算型屬性時,為其提供一個 getter 方法,使其成為唯讀;提供 getter 方法和 setter 方法,使其成為可讀/寫的。更多資訊,請查閱屬性。
拷貝
在 Swift 中,Objective-C 的copy特性被轉換為@NSCopying屬性。這一類的屬性必須遵守 NSCopying協議。更多資訊,請查閱特性。
實現Core Data Managed Object子類
Core Data 提供了基本存放裝置和實現NSManagedObject子類的一組屬性。在 Core Data 模型中,與管理對象子類相關的特性或者關係的每個屬性定義之前,將@NSmanaged特性加入。與 Objective-C 裡面的 @dynamic屬性類別似,@NSManaged特性告知 Swift 編譯器,這個屬性的儲存和實現將在運行時完成。但是,與@dynamic不同的是,@NSManaged特性僅在 Core Data 支援中可用。