Swift進階雜談2:值類型

本文主要介紹值類型程序員

內存分區模型

爲了更好的理解值類型,首先了解內存分區模型,在iOS中,內存主要分爲 棧區 堆區 全局區 常量區 代碼區五大區域。以下圖所示markdown

如圖所示spa

  • 棧區的地址比堆區的地址大。
  • 棧是從高地址->低地址,向下延伸,由系統自動管理,是一片連續的內存地址。
  • 堆是從低地址->高地址,向上延伸,由程序員管理,堆空間結構相似於鏈表,是不連續的。
  • 平常開發中的溢出是指堆棧溢出,能夠理解爲棧區與堆區邊界碰撞的狀況。
  • 全局區、常量區都存儲在__TEXT cString段。

值類型

值類型的特色

  • 一、地址中存儲的是
  • 二、值類型的傳遞過程當中,至關於傳遞了一個副本,也就是所謂的深拷貝
  • 三、值傳遞過程當中,並不共享狀態

舉個例子

func test() {
    var age = 18
    var age2 = age
    age = 30
    age2 = 45
    
    print("age=\(age),age2=\(age2)")
}

test()
複製代碼

斷點查看age的棧區地址與內存狀況code

  • 獲取age的棧區地址:po withUnsafePointer(to: &age){print($0)}
  • 查看age內存狀況:x/8g 0x00007ffeefbff410

一樣查看age2的棧區地址與內存狀況 orm

能夠看出,age2的賦值至關於將age中的值拿出來,賦值給了age2。其中ageage2的地址 相差了8字節,從這裏能夠說明棧空間是連續的、且是從高到低的。內存

結構體是值類型

定義一個結構體,並進行分析開發

struct PDTeacher {
    var age : Int = 16
    var age2: Int = 20
    
}

var t = PDTeacher()
print("end")
複製代碼
  • 打印t:po t,可知,打印出來t就是值,沒有任何與地址有關的信息

  • 獲取t的內存地址,並查看其內存狀況

此時將t賦值給t1,若是修改了t1,t會發生改變嗎?

  • 直接打印t及t1,能夠發現t並無由於t1的改變而改變,主要是由於t1t之間是值傳遞,即t1和t是不一樣的內存空間,是直接將t中的值拷貝t1中。修改t1中的值,是修改的t1的內存空間,是不會影響t的內存空間的。

SIL驗證

一樣的,咱們也能夠經過分析SIL來驗證結構體是值類型it

  • SIL文件中,咱們查看結構體的初始化方法,能夠發現只有init,而沒有malloc,在其中看不到任何關於堆區的分配。

總結

  • 結構體是值類型,且結構體的地址就是第一個成員的內存地址。
  • 值類型在內存中直接存儲值
  • 值類型的賦值,是一個值傳遞的過程,即至關於拷貝了一個副本,存入不一樣的內存空間,兩個空間彼此間並不共享狀態
  • 值傳遞其實就是深拷貝
相關文章
相關標籤/搜索