本文介紹兩部分
Objcetive-c和Swift的區別
Swift3.x - Swift5.x的差異
OC和Swift的區別
Swift是蘋果最近新推出的一門語言但是他還不能起到代替OC的作用。OC之前積累的很多類庫,在Swift中大部分依然可以直接使用,當然,Swift3之后,一些語法改變了很多,不過還是有跡可循的。OC出現過的絕大多數概念,比如引用計數、ARC、屬性、協議、接口、初始化、擴展類、命名參數、block等,在Swift中繼續有效(可能最多換個術語)。Swift大多數概念與OC一樣。當然Swift也多出了一些新興概念,這些在OC中是沒有的,比如范型、元組等。
Swift的優勢 OC的劣勢
- Swift 語法和文件結構簡易化。文件分離后結構更清晰。
- Swift更加安全,它是類型安全的語言。
- Swift速度更快,運算性能更高。
- 不像C語言和OC語言一樣都必須有一個主函數main()作為程序的入口, swift程序從第一句開始向下順序執行, 一直到最后
Swift的劣勢 OC的優勢
- 版本不穩定,每次升級都報好多紅
- Runtime對Swift支持不太友好屏蔽了好多下層Api
Swift 處境
- 使用人數比例偏低,有好多資料查找較為困難
- 一些比較優秀的第三方還是用OC寫的。現在Swift也有不少
- 蘋果推出這門語言肯定會推廣只是時間問題。
Swift3.1 - Swift 5.0 版本的差異
推薦大家一個網站名字叫whats new in swift ,可以看各個版本的歷史差異
借鑒這位老哥的文章
Swift5.0
- 在字符串中包含 " 時不必再加 **,包含 \ 反斜杠也不需要再加轉義符.
var t: String = "123"
var p: String = #"123"t"12"#
print(p)
123"t"12
- 由于反斜杠作為字符串中的字符,所以在插入值的時候需要在后面再加個 #
//before
let answer = 42
let dontpanic = "The answer to life, the universe, and everything is \(answer)"
// after
let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)"#
- 當字符串包含 # 時, 前后應用 ## 包裹字符串
let str = ##"My dog said "woof"#gooddog"##
- 用 #""" 開頭 """#結尾 來表示多行字符串
let multiline =
#"""
The answer to life,
the universe,
and everything is \#(answer).
"""#
- 由于不用反斜杠轉義 使得正則表達式更加簡潔明了
//before
let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+"
//after
let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#
在枚舉新增加一個 @unknown 修飾 default 分支,這樣使得將來 enum 再增加一個 case 的時候,編譯器會在該枚舉的switch 代碼里生成一個警告
integers 新增加了一個 isMultiple(of:) 方法
來檢測一個數是否是另一個數的倍數Sequence 新增加了一個方法 count(where:) 相當于 filter() + count 的結果,但是它更加簡潔一步到位
為字典新增了一個方法 compactMapValues(),正如數組的compactMap函數一樣,可以過濾nil,類型轉換
Swift4.2
枚舉里增加CaseIterable協議自動合成將只發生在不使用關聯值的枚舉中。
#warning和 # error
@dynamicMemberLookup 它指示 swift 在訪問屬性時調用下標方法。此下標方法,subscript(dynamicMember:) 是必需的: 您將獲得所請求的屬性的字符串名稱, 并且可以返回您喜歡的任何值。
@dynamicMemberLookup
struct Person {
subscript(dynamicMember member: String) -> String {
let properties = ["name": "Taylor Swift", "city": "Nashville"]
return properties[member, default: ""]
}
}
@dynamicMemberLookup屬性需要類型來實現下subscript(dynamicMember:)方法來處理動態成員查找的實際工作。正如您所看到的, 我已經編寫了一個接受成員名稱為字符串并返回字符串的名稱, 在內部它只是在字典中查找成員名稱并返回其值。
該結構允許我們編寫如下所示的代碼:
let person = Person()
print(person.name)
print(person.city)
print(person.favoriteIceCream)
- 提供了一種新的allSatisfy()方法, 用于檢查序列中的所有項是否都通過條件。
let scores = [85, 88, 95, 92]
let passed = scores.allSatisfy { $0 >= 85 }
- removeAll(where:)
Swift4.1
- Equatable" 協議 "允許 swift 將類型的一個實例與另一個實例進行比較。當我們說5 == 5時, swift 理解這意味著Int什么, 因為 ant 符合Equatable, 這意味著它實現了一個描述== Int的兩個實例 的函數.
在我們自己的值類型中實現Equatable"使它們能夠像 swift 的字符串、數組、數字等一樣工作, 并且通常最好使結構符合Equatable以便它們更好地符合值類型的概念
struct Person: Equatable {
var firstName: String
var lastName: String
var age: Int
var city: String
static func ==(lhs: Person, rhs: Person) -> Bool {
return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && lhs.age == rhs.age && lhs.city == rhs.city
}
}
即使讀起來很累, 也別管寫了.
幸運的是, Swift 4.1 可以合成公式Equatable的一致性–它可以自動生成==, 它將一個值中的所有屬性與另一個值中的所有屬性進行比較, 就像上面一樣。所以, 現在你要做的就是為你的類型添加Equatable協議, 而 swift 將完成剩下的工作。
當然, 如果你想, 你可以實現 = ==自己。例如, 如果您的類型有一個唯一標識它的id字段, 則可以編寫==比較該單個值, 而不是讓 swift 執行所有額外的工作。
Swift 4.1 還引入了對Hashable的綜合支持, 這意味著它將自動為符合類型生成hashValuevalue 屬性。Hashable實現總是很煩人的, 因為你需要為每個對象返回一個唯一的 (或者至少是唯一的) 哈希。不過, 這一點很重要, 因為它允許您將對象用作字典鍵, 并將其存儲在集合中。
Swift 4.0
Swift 4 引入了一種新Codable, 允許您序列化和反序列化自定義數據類型, 而無需編寫任何特殊代碼, 而無需擔心丟失值類型。更好的是, 您可以選擇數據的序列化方式: 您可以使用經典的屬性列表格式, 甚至可以使用 JSON 格式。
多行字符串文本 """ """ 可以直接聲名多行字符串文本
Objit-c 最受歡迎的功能之一是它能夠動態地而不是直接引用屬性--也就是說, 可以說 "給定對象 X, 這里是我想讀的屬性", 而無需實際閱讀它。這些引用稱為關鍵路徑, 不同于直接屬性訪問, 因為它們實際上不讀取或寫入值, 它們只是將其隱藏起來供以后使用。 Swift最終使用的語法使用了反斜杠: \Starship.name. name, \Starship.maxWarp和\Starship.captain.name。您可以將這兩個變量分配給變量, 然后在任何 Starship 實例上Starship隨時使用它們
字符串變成集合類型
Swift 4 可以將數組進行切片,其中缺失的一側自動推斷為集合的開始或結束。
let characters = ["Dr Horrible", "Captain Hammer", "Penny", "Bad Horse", "Moist"]
let bigParts = characters[..<3]
let smallParts = characters[3...]
print(bigParts)
print(smallParts)
- 改進的字典功能 Swift3中在 Swift 3 中篩選詞典不會返回新詞典。相反, 它返回一個包含 key/值標簽的元組數組。例如:
let cities = ["Shanghai": 24_256_800, "Karachi": 23_500_000, "Beijing": 21_516_000, "Seoul": 9_995_000];
let massiveCities = cities.filter { $0.value > 10_000_000 }
代碼運行后, 您無法讀取massiveCities["Shanghai"] , 因為它不再是字典。相反, 你需要使用massiveCities[0].value, 這不是很好。
從 Swift 4 開始, 這更像你所期望的那樣: 你能得到一本新字典。顯然, 這將破壞依賴于元組數組返回類型的任何現有代碼。
同樣, 字典上的map()沒有像許多人所希望的那樣有效: 您得到了一個傳入的鍵值元組, 并且可以返回要添加到數組中的單個值。例如:
let populations = cities.map { $0.value * 2 }
在 Swift 4 中, 這種情況沒有改變, 但有一種名為mapValues()的新方法將更加有用, 因為它允許您轉換值并使用原始鍵將其放回字典中。