swift4.0新特性的記錄

最新在寫(xiě)swift的時(shí)候感覺(jué)不怎么順手碍扔,于是把新特性看了一遍苏遥,順便做一下筆記氓栈,加深一下記憶。

1拐云、語(yǔ)法改進(jìn)

extesion 中可以訪問(wèn)private的屬性

例:

struct Date: Equatable,Comparable {
    private let secondsSinceReferenceDate: Double
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
    
    static func <(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
    }
    
}

這個(gè)是將Date實(shí)現(xiàn)Equatable罢猪,Comparable的協(xié)議。為了更swift話一下叉瘩,可以將代碼改造成膳帕。


struct Date {
    private let secondsSinceReferenceDate: Double // 結(jié)構(gòu)體中定一個(gè)私有屬性
}

// 擴(kuò)展結(jié)構(gòu)體,實(shí)現(xiàn)Equatable,Equatable協(xié)議
extension Date: Equatable {
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
}

extension Date: Comparable {
    static func <(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
    }
}

swift4能這樣調(diào)用房揭,但是swift3將會(huì)提示錯(cuò)誤备闲,要把Date中的private改成fileprivate晌端,這樣會(huì)把作用域變大,造成屬性的濫用恬砂。而swift4咧纠,就是將private的作用域變大,擴(kuò)展到extension中泻骤,這樣就不必更改屬性的作用域了漆羔。

類型+協(xié)議 生成的組合類型

protocol Shakeable {
    func shake()
}

extension UIButton: Shakeable {
    func shake() {
        print("a")
    }
}
extension UISlider: Shakeable {
    func shake() {
        print("b")
    }
}

func shakeEm(controls: [UIControl & Shakeable]) {
    for control in controls where control.isEnabled {
        control.shake()
    }
}

這樣就可以直接使用類型中遵循協(xié)議的方法,而不必要再判斷cotrol是否遵循這個(gè)協(xié)議狱掂,然后在as一下來(lái)調(diào)用協(xié)議中的方法演痒。

associatedtype 可以追加where的約束

protocol Shakeable {
    associatedtype Element where Self.Element == Self.Iterator.Element
    func shake()
}

這樣可以避免在使用Shakeable時(shí)多做一個(gè)類型判斷

key paths 語(yǔ)法的改變

因?yàn)橐郧暗膶?xiě)法,這個(gè)在swift4上總是寫(xiě)的不舒服趋惨。swift4創(chuàng)建一個(gè)keyPath要用\開(kāi)頭

\keyPath

swift3使用setValue來(lái)寫(xiě)

@objcMembers class Kid: NSObject {
    dynamic var nickname: String = ""
    dynamic var age: Double = 0.0
    dynamic var friends: [Kid] = []
}
var ben = Kid(nickname: "Benji", age: 5.5)
let kidsNameKeyPath = #keyPath(Kid.nickname)
let name = ben.valueForKeyPath(kidsNameKeyPath)
ben.setValue("Ben", forKeyPath: kidsNameKeyPath)

而變成swift4就用了

struct Kid {
    var nickname: String = ""
    var age: Double = 0.0
    var friends: [Kid] = []
}
var ben = Kid(nickname: "Benji", age: 8, friends: [])
let name = ben[keyPath: \Kid.nickname]
ben[keyPath: \Kid.nickname] = "BigBen"

不是很習(xí)慣鸟顺。
swift4的keyPath新特點(diǎn):
1、可以定義class器虾、struct讯嫂,而不必加上@objcMembers、dynamic的關(guān)鍵字
2兆沙、類型安全和類型推斷
3欧芽、可以用在所有的值類型上

下標(biāo)支持泛型

現(xiàn)在下標(biāo)用泛型不需要用as來(lái)轉(zhuǎn)換類型了
例:

struct GenericDictionary<Key: Hashable, Value> {
    private var data: [Key: Value]

    init(data: [Key: Value]) {
        self.data = data
    }

    subscript<T>(key: Key) -> T? {
        return data[key] as? T
    }
}

let dictionary = GenericDictionary(data: ["Name" : "xx"])
let name: String? = dictionary["name"]

字符串

Unicode字符串在計(jì)算count時(shí)的正確性改善

var family = "??"
print(family.characters.count)  // 1

去掉characters

現(xiàn)在string的某些屬性可以不用characters。但是自動(dòng)填充下有些加的characters的類型和不加的類型有些不同葛圃。

可以取單側(cè)邊界

新加語(yǔ)法糖...可以對(duì)字符串取單側(cè)邊界

let v = "hhgggdads"
let startSlicIndex = v.index(v.startIndex, offsetBy: 3)
let subvalue = v[startSlicIndex...]

String實(shí)現(xiàn)了Collection協(xié)議

因?yàn)閷?shí)現(xiàn)了collection協(xié)議千扔,所以現(xiàn)在可以調(diào)用collection 的方法
例:

//翻轉(zhuǎn)字符串
let abc: String = "abc"
print(String(abc.reversed()))

//遍歷
for i in abc {
    print(i)
}

//map
_ = abc.map {
    print($0.description)
}

//filter
let filterd = abc.filter { $0 == "b"}

//reduce
let result = abc.reduce("1") { (result, c) -> String in
    print(result)
    print(c)
    return result + String(c)
}
print(result)

Substring

在 Swift 中,String 的背后有個(gè) Owner Object 來(lái)跟蹤和管理這個(gè) String库正,String 對(duì)象在內(nèi)存中的存儲(chǔ)由內(nèi)存其實(shí)地址曲楚、字符數(shù)、指向 Owner Object 指針組成诀诊。Owner Object 指針指向 Owner Object 對(duì)象洞渤,Owner Object 對(duì)象持有 String Buffer。當(dāng)對(duì) String 做取子字符串操作時(shí)属瓣,子字符串的 Owner Object 指針會(huì)和原字符串指向同一個(gè)對(duì)象,因此子字符串的 Owner Object 會(huì)持有原 String 的 Buffer讯柔。當(dāng)原字符串銷毀時(shí)抡蛙,由于原字符串的 Buffer 被子字符串的 Owner Object 持有了,原字符串 Buffer 并不會(huì)釋放魂迄,造成極大的內(nèi)存浪費(fèi)粗截。

在 Swift 4 中,做取子串操作的結(jié)果是一個(gè) Substring 類型捣炬,它無(wú)法直接賦值給需要 String 類型的地方熊昌。必須用 String() 包一層绽榛,系統(tǒng)會(huì)通過(guò)復(fù)制創(chuàng)建出一個(gè)新的字符串對(duì)象,這樣原字符串在銷毀時(shí)婿屹,原字符串的 Buffer 就可以完全釋放了灭美。

多行字符串字面量

swift4可以把字符串寫(xiě)在一對(duì)"""中,這樣字符串就可以寫(xiě)成多行昂利。

let joke = """
Q: Why does  have  in their name?
A: I don't know, why does  have s in their name?
Q: Because otherwise they'd be called (punchline).
"""

標(biāo)準(zhǔn)庫(kù)

Encoding and Decoding

swift4中引入Codable來(lái)解決對(duì)象持久話問(wèn)題

struct Language: Codable {
    var name: String
    var version: Int
}

將language對(duì)象的實(shí)例持久化届腐,只要language遵循Codable協(xié)議就好,然后encode成json或者PropertyList

//encode
let swift = Language(name:"swift",version: 4)
if let encode = try? JSONEncoder().encode(swift){
    // 保存encode

}

//decode
if let decoded = try? JSONDecoder().decode(Language.self, from: encoded) {
    print(decoded.name)
}

sequence的改進(jìn)

protocol Sequence {
    associatedtype Element
    associatedtype Iterator: IteratorProtocol where Iterator.Element == Element
    func makeIterator() -> Iterator
}

swift4的associatedtype支持追加where語(yǔ)句蜂奸,這樣獲取Sequence的元素類型可以不用 Iterator.Element犁苏,而是直接取 Element。

Protocol-oriented integers

整數(shù)類型符合的協(xié)議有修改扩所,新增了 FixedWidthInteger 等協(xié)議围详,具體的協(xié)議繼承關(guān)系如下

            +-------------+   +-------------+
        +------>+   Numeric   |   | Comparable  |
        |       |   (+,-,*)   |   | (==,<,>,...)|
        |       +------------++   +---+---------+
        |                     ^       ^
+-------+------------+        |       |
|    SignedNumeric   |      +-+-------+-----------+
|     (unary -)      |      |    BinaryInteger    |
+------+-------------+      |(words,%,bitwise,...)|
       ^                    ++---+-----+----------+
       |         +-----------^   ^     ^---------------+
       |         |               |                     |
+------+---------++    +---------+---------------+  +--+----------------+
|  SignedInteger  |    |  FixedWidthInteger      |  |  UnsignedInteger  |
|                 |    |(endianness,overflow,...)|  |                   |
+---------------+-+    +-+--------------------+--+  +-+-----------------+
                ^        ^                    ^       ^
                |        |                    |       |
                |        |                    |       |
               ++--------+-+                +-+-------+-+
               |Int family |-+              |UInt family|-+
               +-----------+ |              +-----------+ |
                 +-----------+                +-----------+

ps:個(gè)人也不是很理解,只是參看了文檔上的解釋祖屏。

Dictionary and Set enhancements

dictionary和set增強(qiáng)的功能:
1短曾、通過(guò)Sequence來(lái)初始化
2、可以包含重復(fù)的Key
3赐劣、Filter的結(jié)果的類型和原類型一致
4嫉拐、dictionary的mapValues方法
5、dictionary的默認(rèn)值
6魁兼、dictionary可以分組
7婉徘、dictionary可以翻轉(zhuǎn)

NSNumber bridging and Numeric types

let n = NSNumber(value: 999)
let v = n as? UInt8 // Swift 4: nil, Swift 3: 231

swift4中,把值為999的NSNumber轉(zhuǎn)換為UInt8后會(huì)返回nil咐汞,而swift3會(huì)返回231這個(gè)意外的值

MutableCollection.swapAt(::)

MutableCollection 現(xiàn)在有了一個(gè)新方法 swapAt(::) 用來(lái)交換兩個(gè)位置的值

var mutableArray = [1, 2, 3, 4]
mutableArray.swapAt(1, 2)
print(mutableArray)
// 打印結(jié)果:[1, 3, 2, 4]

工程上

預(yù)編譯 Bridging Headers 文件

編譯器會(huì)預(yù)編譯 Bridging Headers 文件盖呼,這樣就不要在編譯的時(shí)候每次都編譯oc的頭文件生成的swift文件,從加快了編譯速度化撕。

Indexing 可以在編譯的同時(shí)進(jìn)行

用 Swift 開(kāi)發(fā)項(xiàng)目時(shí)几晤,近幾個(gè)版本的 Xcode 進(jìn)行 Indexing 的速度慢的令人發(fā)指。Xcode 9 和 Swift 4 在這方面做了優(yōu)化植阴,可以在編譯的同時(shí)進(jìn)行 Indexing蟹瘾,一般編譯結(jié)束后 Indexing 也會(huì)同時(shí)完成

COW Existential Containers

Swift 中有個(gè)東西叫 Existential Containers,它用來(lái)保存未知類型的值掠手,它的內(nèi)部是一個(gè) Inline value buffer憾朴,如果 Inline value buffer 中的值占用空間很大時(shí),這個(gè)值會(huì)被分配在堆上喷鸽,然而在堆上分配內(nèi)存是一個(gè)性能比較慢的操作众雷。

Swift 4 中為了優(yōu)化性能引入了 COW Existential Containers,這里的 COW 就代表 “Copy-On-Write”,當(dāng)存在多個(gè)相同的值時(shí)砾省,他們會(huì)共用 buffer 上的空間鸡岗,直到某個(gè)值被修改時(shí),這個(gè)被修改的值才會(huì)被拷貝一份并分配內(nèi)存空間编兄。

移除未調(diào)用的協(xié)議實(shí)現(xiàn)

struct Date {
    private let secondsSinceReferenceDate: Double
}
extension Date: Equatable {
    static func ==(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate == rhs.secondsSinceReferenceDate
    }
}
extension Date: Comparable {
    static func <(lhs: Date, rhs: Date) -> Bool {
        return lhs.secondsSinceReferenceDate < rhs.secondsSinceReferenceDate
    }
}

上面的例子轩性,Date 實(shí)現(xiàn)了 Equatable 和 Comparable 協(xié)議。編譯時(shí)如果編譯器發(fā)現(xiàn)沒(méi)有任何地方調(diào)用了對(duì) Date 進(jìn)行大小比較的方法翻诉,編譯器會(huì)移除 Comparable 協(xié)議的實(shí)現(xiàn)炮姨,來(lái)達(dá)到減小包大小的目的。

減少隱式 @objc 自動(dòng)推斷

在 Swift 4 中碰煌,隱式 @objc 自動(dòng)推斷只會(huì)發(fā)生在很少的當(dāng)必須要使用 @objc 的情況舒岸,比如:

復(fù)寫(xiě)父類的 Objective-C 方法
符合一個(gè) Objective-C 的協(xié)議
其它大多數(shù)地方必須手工顯示的加上 @objc。

減少了隱式 @objc 自動(dòng)推斷后芦圾,Apple Music app 的包大小減少了 5.7%蛾派。

OK筆記就到這,下面是參考資料:

WWDC 2017 Session 402 《What’s New in Swift》
WWDC 2017 Session 212 《What’s New in Foundation》
WWDC 2017 Session 102 《Platforms State of the Union》
《Swift Language Programming (Swift 4.0)》
https://github.com/apple/swift-evolution
https://github.com/ole/whats-new-in-swift-4
https://www.raywenderlich.com/163857/whats-new-swift-4
https://www.hackingwithswift.com/swift4

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末个少,一起剝皮案震驚了整個(gè)濱河市洪乍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夜焦,老刑警劉巖壳澳,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異茫经,居然都是意外死亡巷波,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門卸伞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)抹镊,“玉大人,你說(shuō)我怎么就攤上這事荤傲】宥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵遂黍,是天一觀的道長(zhǎng)终佛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)妓湘,這世上最難降的妖魔是什么查蓉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮榜贴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己唬党,他們只是感情好鹃共,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著驶拱,像睡著了一般霜浴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓝纲,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天阴孟,我揣著相機(jī)與錄音,去河邊找鬼税迷。 笑死永丝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的箭养。 我是一名探鬼主播慕嚷,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毕泌!你這毒婦竟也來(lái)了喝检?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撼泛,失蹤者是張志新(化名)和其女友劉穎挠说,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體愿题,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡损俭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抠忘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撩炊。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖崎脉,靈堂內(nèi)的尸體忽然破棺而出拧咳,到底是詐尸還是另有隱情,我是刑警寧澤囚灼,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布骆膝,位于F島的核電站,受9級(jí)特大地震影響灶体,放射性物質(zhì)發(fā)生泄漏阅签。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一蝎抽、第九天 我趴在偏房一處隱蔽的房頂上張望政钟。 院中可真熱鬧,春花似錦、人聲如沸养交。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碎连。三九已至灰羽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鱼辙,已是汗流浹背廉嚼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留倒戏,地道東北人怠噪。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像峭梳,于是被迫代替她去往敵國(guó)和親舰绘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容