Swift互用性: 使用Objective-C特性編寫Swift類(Swift 2.0版)

jopen 10年前發布 | 16K 次閱讀 Swift Apple Swift開發

Swift互用性: 使用Objective-C特性編寫Swift類(Swift 2.0版)

本文由CocoaChina翻譯小組成員翻譯自蘋果官方文檔 Using Swift with Cocoa and Objective-C:Writing Swift Classes with Objective-C Behavior
譯者:halinuya(GitHub)  校對:song-buaa(GitHub) MonicaZhou (GitHub)ChildhoodAndy(GitHub)

該系列文檔已在 CocoaChina的GitHub主頁 更新,歡迎小伙伴參與進來,閱讀校正,補充遺漏。
若翻譯和校對人員有遺漏,小伙伴一定要提醒CC更正啦。


Using Swift with Cocoa and Objective-C(Swift 2.0版): 使用Objective-C特性編寫Swift類
本節包括內容:

  • 繼承Objective-C的類(Inheriting from Objective-C Classes)

    </li>

  • 采用協議(Adopting Protocols)

    </li>

  • 編寫構造器和析構器(Writing Initializers and Deinitializers)

    </li>

  • 集成Interface Builder(Integrating with Interface Builder)

    </li>

  • 指明屬性特性(Specifying Property Attributes)

    </li>

  • 實現Core Data Managed Object子類(Implementing Core Data Managed Object Subclasses)

    </li>

  • 使用帶Objective-C API的Swift類名

    </li> </ul>

    互用性(互操作性)使開發者可以定義融合了 Objective-C 語言特性的Swift類。編寫 Swift 類時,不僅可以繼承 Objective-C 語言編寫的父類,采用 Objective-C 的協議,還可以利用 Objective-C 的一些其它功能。這意味著,開發者可以基于 Objective-C 中已有的熟悉、可靠的類、方法和框架來創建 Swift 類,并結合 Swift 提供的現代化和更有效的語言特點對其進行優化。

    繼承Objective-C的類

    在 Swift 中,開發者可以定義一個子類,該子類繼承自使用 Objective-C 編寫的類。創建該子類的方法是,在 Swift 的類名后面加上一個冒號(:),冒號后面跟上 Objective-C 的類名。

    import UIKit
    class MySwiftViewController: UIViewController {
        // 定義類
    }

    開發者能夠從 Objective-C 的父類中繼承所有的功能。如果開發者要覆蓋父類中的方法,不要忘記使用override關鍵字。

    NSCoding協議

    NSCoding協議要求符合的類型實現所需的構造器init(coder:)。直接采用NSCoding協議的類必須實現這個方法。采用NSCoding協議的類的子類,這些類有一個或者多個自定義的構造器或者不帶初始化值的屬性,也必須實現這個方法。Xcode提供了以下占位實現來提醒:

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    對那些從 Storyboards 里加載的對象,或者用 NSUserDefaults 或 NSKeyedArchiver 類歸檔到磁盤的對象,你必須提供一個完整的初始化程序的實現。然而,當類型以此種方式無法實例化的時候,你可能并不需要實現構造器。

    采用協議

    在 Swift 中,開發者可以采用 Objective-C 中定義好的協議。和 Swift 協議一樣,所有 Objective-C 協議都寫在一個用逗號隔開的列表中,跟在所在類的父類名后面(如果它有父類的話)。

    class MySwiftViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
        // 定義類
    }

    Objective-C 協議與 Swift 協議使用上是一致的。如果開發者想在 Swift 代碼中引用 UITableViewDelegate協議,可以直接使用UITableViewDelegate(跟在 Objective-C 中引用id是等價的)。

    因為在 Swift 中,類和協議的命名空間是統一的,Objective-C 里的 NSObject 協議被重新映射到 Swift 里的 NSObjectProtocol。

    編寫構造器和析構器

    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(Objective-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、Outlet 集合和 Action 的類:

    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 里后,就可以在監視器面板中編輯這些屬性。

    @IBDesignable
    class MyCustomView: UIView {
        @IBInspectable var textColor: UIColor
        @IBInspectable var iconHeight: CGFloat
        /* ... */
    }

    指明屬性特性

    在 Objective-C 中,屬性通常都有一組特性(Attributes)說明來指明該屬性的一些附加信息。在 Swift 中,開發者可以通過不同的方法來指明屬性的這些特性。

    強類型和弱類型

    Swift 里屬性默認都是強類型的。使用weak關鍵字修飾一個屬性,能指明其對象存儲時是一個弱引用。該關鍵字僅能修飾 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 支持中可用。

    Swift 類被命名空間化---他們局限于被編譯的模塊中(最典型的是Target)。 為了使用帶 Core Data 模型的NSManagedObject類的 Swift 子類,在模型實體監視器的類區域里,用模塊名字作為類名的前綴。

    Swift互用性: 使用Objective-C特性編寫Swift類(Swift 2.0版)

    使用帶Objective-C API的Swift類名

    Swift 類的命名基于他們被編譯的模塊,即使是使用來自 Objective-C 的代碼。和 Objective-C 不同的是,所有的類都是全局命名空間的一部分,必須沒有相同的名字,Swift 類可以基于他們存在的模塊來消除歧義。比如,被稱為 MyFramework 框架中的被叫做DataManager 的 Swift 類的全限定名就是 MyFramework.DataManager。一個 Swift 應用目標就是模塊本身,所以,在一個叫 MyGreatApp 的應用里,叫 Observer 的 Swift 類的全限定名是 MyGreatApp.Observer。

    為了保存在 Objective-C 代碼里使用的 Swift 類,Swift類用他們的全限定名暴漏給 Objective-C 運行時。因此,當你使用那些對 Swift 類的字符串代表起作用的 API,必須包含類的全限定名。比如,當你創建一個基于文檔的 Mac 應用,要在應用的 Info.plist 里提供 NSDocument 子類的名字。Swift里,你必須使用文檔子類的全名,包括從你的應用或者框架里派生出來的模塊名字。 下面的例子中,NSClassFromString方法用于檢索一個來自字符串代表的類的引用。為了檢索 Swift 類,需要使用全限定名,包括應用的名字。

    let myPersonClass:AnyClass(NSClassFromString("MyGreatApp.Person"))
    來源:CocoaChina github主頁

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!