欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Swift可選值優(yōu)化示例詳解

 更新時間:2023年06月19日 11:46:15   作者:云音樂技術(shù)團隊  
這篇文章主要為大家介紹了Swift可選值優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

nil 的語義

在 Objective-C 中,nil 表示空對象,它本質(zhì)是一個指向 0x00000000 的指針。但對于非指針的值類型,OC 中是無法表示_沒有值_這個概念的,比如 NSInteger,它可以是 0,也可以是其他任何值,但就是不存在_沒有值_。

Swift 作為一種強類型的語言,它從一開始就引入了_沒有值_這個概念,雖然還是用 nil 關(guān)鍵字,但實際語義上有所不同。比如 Int?,它可以是 nil,也可以是 00 是一個具體的值,而 nil 不是。然而,計算機作為一個二進制的機器,它內(nèi)存中保存的非 0 即 1,如何表示_沒有值_呢?換句話說,nil 在內(nèi)存中究竟是什么?我們可以通過簡單的代碼找出它在內(nèi)存中的真相。

nil 在內(nèi)存中的表示

/// 以下方法取 value 的地址,并從地址處向后取它在內(nèi)存中的大小 size 個字節(jié),轉(zhuǎn)為對應(yīng)的數(shù)組
func bytes<T>(of value: T) -> [UInt8] {
    var value = value
    let size = MemoryLayout<T>.size
    return withUnsafePointer(to: &value, {
        $0.withMemoryRebound(
            to: UInt8.self,
            capacity: size,
            {
                Array(UnsafeBufferPointer(
                    start: $0, count: size))
            })
    })
}
var int: Int? = 0
bytes(of: int)    // [0, 0, 0, 0, 0, 0, 0, 0, 0]
int = nil
bytes(of: int)    // [0, 0, 0, 0, 0, 0, 0, 0, 1]

從上面我們可以得知,可選的 Int? 類型比普通 Int 類型多占一個字節(jié),用來表示是不是 沒有值。如果這樣的話,在 struct 或 class 中用可選類型豈不是會浪費較多內(nèi)存空間?因為內(nèi)存對齊的緣故,多一個字節(jié),就要浪費剩下的 7 字節(jié),比如:

struct N {
    var b: Int? = 2
    var a: Int? = 3
}
var n = N()
bytes(of: n)    // [2, 0, 0, 0, 0, 0, 0, 0, 0, 76, 68, 3, 1, 0, 0, 0, 
                //  3, 0, 0, 0, 0, 0, 0, 0, 0]

以上原本可以用 16 字節(jié)表示的結(jié)構(gòu)體,實際上占了 25 字節(jié)(考慮結(jié)尾處內(nèi)存對齊,其實占了 32 字節(jié))。我們在實際開發(fā)中,可能會在 class 中聲明大量的可選字段,如果都這樣的話,那內(nèi)存使用率也太低了,有優(yōu)化手段嗎?

答案是有的,而且 Swift 編譯器已經(jīng)默默幫我們做了。

nil 的優(yōu)化

Bool

Bool 類型理論上只用 0 1 兩個值,一個 bit 即可,但它卻占了一整個 byte ,剩下的幾個 bit 是可以用來區(qū)分是否有值的。

var b: Bool? = false
bytes(of: b) // [0]
b = true
bytes(of: b) // [1]
b = nil
bytes(of: b) // [2]

從以上結(jié)果得知,Swift 用 2 表示 Bool? 的_沒有值_,所以沒有內(nèi)存浪費。這樣也使得 Bool? 不再是兩態(tài)的開關(guān),而是一個三態(tài)的開關(guān)。于是經(jīng)常在代碼中看到看起來比較蠢的寫法:

var value: Bool?
if value == true {
}

因為一般來說是不建議 Bool 值與 true 判斷等的,它本身已經(jīng)是 Bool 了。而在 Swift 中又用起來是那么自然……

String

String 類型不同于 Int 這種——0 也是合法值,String 的內(nèi)存值為 0 是可以表示_沒有值_的,所以它也沒有內(nèi)存浪費

String 在 Swift 中是一個結(jié)構(gòu)體,無論字符串多長,String 變量本身只占 16 字節(jié),短的字符串通過類似 OC 中 Tagged Pointer 的技術(shù)直接存在指針中,長的字符串需要指向堆內(nèi)存地址。

Class

Class 類型同 OC 中的一樣,是指針類型,空指針可以表示_沒有值_,沒有內(nèi)存浪費。

class MyObject {
    var b: Int? = 2
    var a: Int? = 3
}
var o: MyObject? = .init()
bytes(of: o)  // [160, 142, 188, 2, 0, 96, 0, 0]
o = nil
bytes(of: o)  // [0, 0, 0, 0, 0, 0, 0, 0]

無論 Class 中有多少成員變量,Class 變量本身(即指向它的指針)只占 8 字節(jié)(64位系統(tǒng)中)。

Enum

枚舉類型一般是有限的,最終總可以找到一個不在枚舉范圍內(nèi)的值表示 _沒有值_,也可以沒有內(nèi)存浪費。

enum Edge {
    case left
    case right
    case top
    case bottom
}
var e: Edge? = .left
bytes(of: e)  // [0]
e = .bottom
bytes(of: e)  // [3]
e = nil
bytes(of: e)  // [4],用越界值表示 nil,沒有值

當(dāng)然并不是所有 Enum 類型都能這樣,帶關(guān)聯(lián)值的就可能不行。

結(jié)語

綜上所述,Swift 編譯器會盡可能地優(yōu)化可選值的內(nèi)存占用,日常開發(fā)并不需要太多關(guān)心,但是部分情況仍要求開發(fā)者盡量少使用可選值,如結(jié)構(gòu)體中連續(xù)幾個可選 Int 的情況,如果 0 也能滿足代碼邏輯,就使用非可選值,并用 0 初始化它吧!

// 浪費的內(nèi)存比較可觀
struct My {
   var a: Int?
   var b: Int?
   var c: Int?
   var d: Int?
}

以上就是Swift可選值優(yōu)化示例詳解的詳細內(nèi)容,更多關(guān)于Swift可選值優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理詳解

    Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理詳解

    這篇文章主要給大家介紹了關(guān)于Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Swift利用AFN實現(xiàn)封裝網(wǎng)絡(luò)請求詳解

    Swift利用AFN實現(xiàn)封裝網(wǎng)絡(luò)請求詳解

    網(wǎng)絡(luò)請求工具是我們經(jīng)常用到的工具類,所以下面這篇文章主要給大家介紹了關(guān)于Swift利用AFN如何實現(xiàn)封裝網(wǎng)絡(luò)請求的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • swift 字符串String的使用方法

    swift 字符串String的使用方法

    這篇文章主要介紹了swift 字符串String的使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Swift自定義UITableViewCell背景色

    Swift自定義UITableViewCell背景色

    這篇文章主要為大家詳細介紹了Swift自定義UITableViewCell背景色,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 深入理解Swift中的訪問控制關(guān)鍵字

    深入理解Swift中的訪問控制關(guān)鍵字

    這篇文章主要給大家介紹了Swift中訪問控制關(guān)鍵字的相關(guān)資料,文中介紹的非常詳細,對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • Swift 中閉包的簡單使用

    Swift 中閉包的簡單使用

    這篇文章主要介紹了Swift 中閉包的簡單使用的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • SwiftUI智能家居開關(guān)燈頁面搭建示例

    SwiftUI智能家居開關(guān)燈頁面搭建示例

    這篇文章主要為大家介紹了SwiftUI智能家居開關(guān)燈頁面搭建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Swift讓輸入框跟隨鍵盤彈起避免輸入輸入法擋住輸入框問題

    Swift讓輸入框跟隨鍵盤彈起避免輸入輸入法擋住輸入框問題

    這篇文章主要介紹了Swift讓輸入框跟隨鍵盤彈起避免輸入輸入法擋住輸入框問題的完美解決方案,本文分步驟給大家介紹的非常詳細,需要的朋友可以參考下
    2016-11-11
  • EvenLoop模型在iOS的RunLoop應(yīng)用示例

    EvenLoop模型在iOS的RunLoop應(yīng)用示例

    這篇文章主要為大家介紹了EvenLoop模型在iOS的RunLoop應(yīng)用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Swift的開發(fā)環(huán)境搭建以及基本語法詳解

    Swift的開發(fā)環(huán)境搭建以及基本語法詳解

    這篇文章主要介紹了Swift的開發(fā)環(huán)境搭建以及基本語法詳解,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11

最新評論