自從蘋果在2014年發佈了本身的Swift編程語言以後,不少開發人員都利用這個機會來測試它的特性,看看它是如何與Objective-C進行比較的。 通常結論彷佛是: 在某些狀況下,Swift比Objective-C更可取。 ###Swift的優勢是什麼?編程
這些功能使Swift很是誘人。 讓咱們考慮若是你決定從Objective-C切換到Swift你須要作什麼,並肯定是否應該轉移到Swift上。 值得一提的是,Swift與Objective-C徹底兼容。 Apple提供了一個混合和匹配功能,容許開發人員在同一個項目中使用這兩種語言。 這意味着您能夠向現有的代碼庫添加新的Swift功能。 同時,儘管Swift和Objective-C使用相同的API,但在從Objective-C遷移到Swift時,您必須記住一些差別。swift
###Optional 類型後端
在Objective-C中,你能夠調用nil對象的方法(更準確地說,你能夠發送消息到nil對象),這些方法返回一個空值。爲了防止在出現意外的nil值時出現未定義的行爲,您須要在須要時執行nil檢查。 Swift引入了可選值的概念。可選類型聲明爲相似枚舉:數組
public enum可選<Wrapped>:_Reflectable,NilLiteralConvertible
複製代碼
從編程上來講,它是一種類型,能夠表明Wrapped類型的值或不存在的值。 Swift提供了使類型可選的語法糖,因此不須要聲明Optional ,你能夠只寫String?您有兩個選項從可選容器獲取包裝的值。第一個是可選連接 - if-let條件語句僅當它存在時才接收該值。若是您徹底肯定可選變量是非零,您可使用強制解包。這提供了存儲的值,若是存在,沒有條件,可是當你犯了一個錯誤,而且可選實例爲空時崩潰。 除了常規可選項,還有隱含的展開可選項,聲明爲String!讓咱們來看看你能夠用不一樣的方式聲明可選性。bash
class ExampleClass {
var nonOptionalString: String
var unwrappedOptionalString: String!
var optionalString: String?
init(string: String) {
nonOptionalString = string
}
}
複製代碼
nonOptionalString永遠不能爲nil。 此屬性應在對象初始化期間填充。 提供強制解包的nil對象將致使崩潰。 unwrappedOptionalString能夠是nil,但若是您嘗試訪問nil對象,您的程序將崩潰。 optionalString能夠爲nil,應被視爲常規可選變量。 當編寫Objective-C代碼時,可使用_Nullable和_Nonnull類型註釋來標記變量。 上面的Swift示例的Objective-C等價相似於:app
@interface ExampleClass: NSObject
@property (nonatomic, strong) NSString * _Nonnull nonOptionalString;
@property (nonatomic, strong) NSString *unwrappedOptionalString;
@property (nonatomic, strong) NSString * _Nullable optionalString;
- (instancetype)initWithString:(nonnull NSString *string);
@end
複製代碼
###錯誤處理編程語言
當在Objective-C中拋出和處理錯誤時,方法的最後一個參數是對NSError變量的引用。 若是此方法執行致使不可接受的行爲,則應建立一個NSError實例並將其寫入傳遞的變量。 在調用可能產生錯誤的方法後,您應該檢查錯誤參數,以確保它是非零。工具
- (nonnull NSString *)exampleMethod:(nonnull NSString *)param error:(NSError **)error {
if (!param.length) {
*error = [NSError errorWithDomain:[NSBundle mainBundle].bundleIdentifier
code:-101
userInfo:nil];
return nil;
} // do work}
複製代碼
Objective-C還提供了一個具備傳統try-catch-finally語法的異常機制,可是Apple強烈建議僅將其用於開發目的。 Swift要求您標記使用throws關鍵字生成錯誤的方法。 若是該方法接受的最後一個參數是指向Objective-C接口中的NSError實例的指針,那麼它將從Objective-C翻譯爲Swift做爲throwing方法,上面方法的聲明將轉換爲 :測試
func exampleMethod(param:String)throws - > String
複製代碼
Objective-C容許你省略錯誤處理的錯誤返回方法,但在Swift你必須明確處理錯誤。 被拋出的對象應該是Swift ErrorType的後代。 ###枚舉ui
Objective-C提供C風格的枚舉,它只限於基本類型。 即便您須要將整數枚舉值映射到相應的字符串以顯示給用戶或發送到後端,也必須建立數組或字典 - 或使用switch語句。 但Swift提供了全新的枚舉與更多的選擇。 Swift中的枚舉能夠按照與Objective-C中相同的方式使用:
enum ExampleEnum {
case ExOne, ExTwo, ExThree
}
複製代碼
Swift枚舉能夠存儲關聯的值。 每一個枚舉大小寫均可以包含一組預約義的字段。
enum AnotherExampleEnum {
case ExOne(String, Int)
case ExTwo(Int)
}
複製代碼
Swift枚舉能夠存儲原始值並遞歸。 Swift還有各類強大的功能,它與Objective-C區別開來。 這些功能包括泛型,嚴格類型系統,類型推斷,元組和嵌套類型。 簡而言之,從Objective-C遷移到Swift不是一件小事。 這裏有一些提示,使過程更容易。 ###從Objective-C遷移到Swift的提示
首先,您應該建立一個與相應頭和實現文件名稱相同的.swift文件。 若是你須要重新的Swift文件中訪問Objective-C類,你必須爲它們添加一個import指令到橋接頭文件。 若是你須要從Objective-C代碼訪問新的Swift類,你必須從Objective-C類繼承它; 不然將沒法訪問。 而後你必須手動重寫代碼,採用Swift的最佳實踐並使類向下兼容。 若是你的Google「從Objective-C遷移到Swift」,你會發現幾個連接,建議自動翻譯代碼的工具。 有免費和付費解決方案。 然而,即便付費的解決方案在它們的功能上極其有限。 爲了看看這些工具是如何在Objective-C中建立一個很是基本的遊戲,而後嘗試使用幾個自動翻譯器將它翻譯成Swift。咱們嘗試的第一個是基於Web的,並容許您上傳一個完整的Xcode項目(可是隻有當項目小於10 MB)。結果然的沒有準備好生產 - 咱們發現超過70個錯誤,即便咱們的程序只有7個小類。這些錯誤包括不正確的可選,不正確的類型推斷,留下最後一個參數爲NSError,而不是切換到Swift錯誤處理與try-catch,從__weak不正確切換typeof(self)weakSelf = self;到[weak self]等。咱們還測試了一個付費桌面應用程序,花費15美圓,但結果更糟。咱們測試的桌面應用程序沒法導入整個項目,所以咱們不得不按文件複製和粘貼全部文件。 行業中的大多數人都贊成Swift正在成爲iOS開發的主要語言,所以建議將它用於新項目。 方便地是,混合和匹配特性容許您使用Swift和Objective-C類做爲同一項目的一部分,所以您沒必要花費時間重寫Swift中的整個現有代碼庫。