標籤:style blog http color 使用 strong
Swift與Objective-C的相容能力允許你在同一個工程中同時使用兩種語言。你可以用這種叫做“mix and match”的特性來開發基於混合語言的應用。使用Swfit的最新特性--“mix and match”,你可以實現應用的一部分功能,並無縫地併入已有的Objective-C的代碼中。
Mix and Match 概述Swift與Objective-C檔案可以在一個工程中並存,不管這個工程原本是基於Objective-C還是Swift。你可以直接往現有工程中簡單地添加另一種語言的檔案。這種自然的工作流程使得建立混合語言的應用或framework target,與用單獨一種語言時一樣簡單。 編寫混合語言的工作流程只有一點點區別,這取決於你是在寫應用還是寫架構。下面描述了用兩種語言在一個target中匯入模型的情況,後續章節會有更多細節。
在同一個App Target中進行代碼匯入如果你在寫混合語言的應用,可能需要用Swift代碼訪問Objective-C代碼,或者反之。本章描述的流程適用於non-framework target。
將Objective-C匯入Swift要在同一個app target中匯入Objective-C檔案供Swift使用,你需要依賴Objective-C的橋接標頭檔(Objective-C bridging header)來暴露給 Swift。當你添加 Swift 檔案到現有的Objective-C應用時,Xcode 會自動建立這些標頭檔,反之亦然。如果你同意,Xcode 會在源檔案建立的同時產生標頭檔,並用product的模組名加上 -Bridging-Header.h命名。關於 product 的模組名,詳見 Naming Your Product Module。 你應該編輯這個標頭檔來對Swift暴露出Objective-C代碼。
在同一target中將Objective-C代碼匯入到Swift中 1.在Objective-C橋接標頭檔中,匯入任何你想暴露給 Swift 的標頭檔,例如:OBJECTIVE-C
#import "XYZCustomCell.h" #import "XYZCustomView.h" #import "XYZCustomViewController.h"
2.在Build Settings中,確保Objective-C橋接標頭檔的build setting是基於 Swfit 編譯器,即Code Generation 含有標頭檔的路徑。這個路徑必須是標頭檔自身的路徑,而不是它所在的目錄。 這個路徑應該是你工程的相對路徑,類似 Info.plist 在 Build Settings 中指定的路徑。在大多數情況下,你不需要修改這個設定。 在這個橋接標頭檔中列出的所有公開的Objective-C 標頭檔都會對 Swift 可見。之後當前 target 的所有 Swift 檔案都可以使用這些標頭檔中的方法,不需要任何import語句。用 Swift 文法使用這些Objective-C代碼,就像使用系統內建的類一樣。SWIFT
let myCell = XYZCustomCell() myCell.subtitle = "A custom cell"
將 Swift 匯入Objective-C向Objective-C中匯入Swift代碼時,你依賴 Xcode 產生的標頭檔來向Objective-C暴露 Swift 代碼。這個自動產生Objective-C標頭檔,聲明了target 中所有 Swift 代碼中定義的介面。可以把這個Objective-C標頭檔看作 Swift 代碼的umbrella header。它以 product 模組名加 -Swift.h 來命名。關於 product 的模組名,詳見 Naming Your Product Module。 你不需要做任何事情來產生這個標頭檔,只需要將它匯入到你的Objective-C代碼來使用它。注意這個標頭檔中的 Swift 介面包含了它所使用到的所有 Objc 類型。如果你在 Swift 代碼中使用你自己的Objective-C類型,確保先將對應的 Objc 標頭檔匯入到你的 Swift 代碼中,然後才將 Swift 自動產生的標頭檔匯入到 Objc .m 源檔案中來訪問 Swift 代碼。
在同一target中將Swift代碼匯入到Objective-C中 在相同 target 的 Objc .m 源檔案中,用下面的文法來匯入Swift 代碼:OBJECTIVE-C
#import “ProductModuleName-Swift.h”
target 中任何 Swift 檔案將會對 Objc .m 檔案可見,包括這個 import 語句。關於在 Objc 代碼中使用 Swift 代碼,詳見 Using Swift from Objective-C。
在同個Framework Target中匯入代碼如果你在寫一個混合語言的架構,可能會從 Swift 代碼訪問 Objc 代碼,或者反之。
將 Objc 匯入 Swift要將一些 Objc 檔案匯入到同個架構 target 的 Swift 代碼中去,你需要將這些檔案匯入到 Objc 的 umbrella header 來供架構使用。
在同一framework中將Objective-C代碼匯入到Swift中 確保將架構 target 的 Build Settings > Packaging > Defines Module 設定為 Yes 。然後在你的 umbrella header 標頭檔中匯入你想暴露給 Swift 訪問的 Objc 標頭檔,例如:OBJECTIVE-C
#import <XYZ/XYZCustomCell.h> #import <XYZ/XYZCustomView.h> #import <XYZ/XYZCustomViewController.h>
Swift 將會看到所有你在 umbrella header 中公開暴露出來的標頭檔,架構 target 中的所有 Swift 檔案都可以訪問你 Objc 檔案的內容,不需要任何 import 語句。SWIFT
let myCell = XYZCustomCell() myCell.subtitle = "A custom cell"
將 Swift 匯入 Objc要將一些 Swift 檔案匯入到同個架構的 target 的 Objc 代碼去,你不需要匯入任何東西到umbrella header檔案,而是將 Xcode 為你的Swift代碼自動產生的標頭檔匯入到你的 Obj .m 源檔案去,以便在 Objc 代碼中訪問 Swift 代碼。
在同一framework中將Swift代碼匯入到Objective-C中 1.確保將架構target 的 Build Settings > Packaging 中的 Defines Module 設定為 Yes 。用下面的文法將 Swift 代碼匯入到同個架構 target 下的 Objc .m 源檔案去。OBJECTIVE-C
#import <ProductName/ProductModuleName-Swift.h>
這個 import 語句所包含的 Swift 檔案都可以被同個架構 target 下的 Objc .m 源檔案訪問。關於在 Objc 代碼中使用 Swift 代碼,詳見 Using Swift from Objective-C。
匯入外部 Framework你可以匯入外部架構,不管這個架構是純 Objc,純 Swift,還是混合語言的。import 外部架構的流程都是一樣的,不管這個架構是用一種語言寫的,還是包含兩種語言。當你匯入外部架構時,確保 Build Setting > Pakaging > Defines Module 設定為 Yes 。 用下面的文法將架構匯入到不同 target 的 Swift 檔案中:SWIFT
import FrameworkName
用下面的文法將架構匯入到不同 target 的 Objc .m 檔案中:OBJECTIVE-C
@import FrameworkName;
在Objective-C中使用 Swift當你將 Swift 代碼匯入 Objc 檔案之後,用普通的 Objc 文法使用 Swift 類。OBJECTIVE-C
MySwiftClass *swiftObject = [[MySwiftClass alloc] init]; [swiftObject swiftMethod];
Swift 的類或協議必須用 @objc attribute 來標記,以便在 Objc 中可訪問。這個 attribute 告訴編譯器這個 Swift 代碼可以從 Objc 代碼中訪問。如果你的 Swift 類是 Objc 類的子類,編譯器會自動為你添加 @objc attribute 。詳見 Swift Type Compatibility。 你可以訪問 Swift 類或協議中用 @objc attribute 標記過東西,只要它和 Objc 相容。不包括一下這些 Swift 專屬的特性:Generics - 範型 Tuples - 元組 Enumerations defined in Swift - Swift 中定義的枚舉 Structures defined in Swift - Swift 中定義的結構體 Top-level functions defined in Swift - Swift Swift 中定義的頂層函數 Global variables defined in Swift - Swift 中定義的全域變數 Typealiases defined in Swift - Swift 中定義的類型別名 Swift-style variadics Nested types - 巢狀型別 Curried functions - 柯裡化後的函數 例如帶有範型類型作為參數,或者返回元組的方法不能在Objective-C中使用。 為了避免循環參考,不要將 Swift 代碼匯入到Objective-C標頭檔中。但是你可以在Objective-C標頭檔中前向聲明( forward declare )一個 Swift 類來使用它,然而,注意不能在Objective-C中繼承一個 Swift 類。
在Objective-C標頭檔中引用Swift類 這樣前向聲明 Swift 類:OBJECTIVE-C
// MyObjcClass.h @class MySwiftClass; @interface MyObjcClass : NSObject - (MySwiftClass *)returnSwiftObject; /* ... */ @end
Product Module命名Xcode 為 Swift 代碼產生的標頭檔的名稱,以及 Xcode 建立的 Objc 橋接標頭檔名稱,都是從你的 product 模組名產生的。預設你的 product 模組名和 product 名一樣。然而,如果你的 product 名有特殊字元(nonalphanumeric,非數字、字母的字元),例如點號,那麼它們會被底線( _ )替換之後作為你的 product 模組名。如果 product 名以數字開頭,那麼第一個數字會用底線替換掉。 你可以給 product 模組名提供一個自訂的名稱,Xcode 會用這個名稱來命名橋接的和自動產生的標頭檔。你只需要在修改在 build setting 中的 Product Module Name 即可。
故障排除和提醒•把 Swift 和 Objc 檔案看作相同的代碼集合,並注意命名衝突; •如果你用架構,確保 Build Setting > Pakaging > Defines Module 設定為 Yes ; •如果你使用 Objc 橋接標頭檔,確保在 Build Settings 中 Objc 橋接標頭檔的 build setting 是基於 Swfit 編譯器,即 Code Generation 含有標頭檔的路徑。這個路徑必須是標頭檔自身的路徑,而不是它所在的目錄。 •Xcode 使用你的 product 模組名,而不是 target 名來命名 Objc 橋接標頭檔和為 Swift 自動產生的標頭檔。詳見 Naming Your Product Module; •為了在 Objc 中可用, Swift 類必須是 Objc 類的子類,或者用 @objc 標記; •當你將 Swift 匯入到 Objc 中時,記住 Objc 不會將 Swift 專屬的特性翻譯成 Objc 對應的特性。詳見列表 Using Swift from Objective-C; •如果你在 Swift 代碼中使用你自己的 Objc 類型,確保先將對應的 Objc 標頭檔匯入到你的 Swift 代碼中,然後才將 Swift 自動產生的標頭檔 import 到 Objc .m 源檔案中來訪問 Swift 代碼。 本章由CocoaChina的翻譯小組成員
haolloyin(
github首頁
)翻譯,轉載請註明出處和譯者資訊,拒絕商業之用。
http://www.cocoachina.com/newbie/basic/2014/0605/8688.html
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_85