<abbr id="ciwa6"><option id="ciwa6"></option></abbr>
  • <sup id="ciwa6"><kbd id="ciwa6"></kbd></sup>
    <small id="ciwa6"></small>
  • 千鋒教育-做有情懷、有良心、有品質的職業教育機構

    400-811-9990
    手機站
    千鋒教育

    千鋒學習站 | 隨時隨地免費學

    千鋒教育

    掃一掃進入千鋒手機站

    領取全套視頻
    千鋒教育

    關注千鋒學習站小程序
    隨時隨地免費學習課程

    上海
    • 北京
    • 鄭州
    • 武漢
    • 成都
    • 西安
    • 沈陽
    • 廣州
    • 南京
    • 深圳
    • 大連
    • 青島
    • 杭州
    • 重慶
    當前位置:成都千鋒IT培訓  >  技術干貨  >  swift中結構體和類的區別(值類型和引用類型的區別)?

    swift中結構體和類的區別(值類型和引用類型的區別)?

    來源:千鋒教育
    發布人:xqq
    時間: 2023-10-17 14:43:02

    一、swift中結構體和類的區別

    類是引用類型,存儲在堆區;結構體是值類型,存儲在棧區。類有繼承特性;結構體沒有。類實例可以被多次引用,有引用計數。結構體沒有引用計數,賦值都是值拷貝。類有反初始化器(deinit)來釋放資源。類型轉換允許你在運行時檢查和解釋一個類實例的類型。

    值類型 vs 引用類型

    結構體是值類型,實際上,Swift 中所有的基本類型:整數,浮點數,布爾量,字符串,數組和字典,還有枚舉,都是值類型,并且都以結構體的形式在后臺實現。

    這意味著字符串,數組和字典在被賦值到一個新的常量或變量,或者它被傳遞到一個函數或方法中的時候,其實是傳遞了值的拷貝。這不同于 OC 的 NSString,NSArray 和 NSDictionary,他們是類,屬于引用類型,賦值和傳遞都是引用。

    值類型存儲的是值,賦值時都是進行值拷貝,相互之間不會影響。而引用類型存儲的是對象的內存地址,賦值時拷貝指針,都是指向同一個對象,即同一塊內存空間。

    1、結構體是值類型

    swift

    復制代碼

    struct Book {

    ??? var name: String

    ??? var high: Int

    ??? func turnToPage(page:Int) {

    ??????? print(“turn to page \(page)”)

    ??? }

    }

    var s = Book(name: “程序員的自我修養”, high: 8)

    var s1 = s

    s1.high = 10

    print(s.high, s1.high) // 8 10

    這段代碼中初始化結構體high為18,賦值給s1時拷貝整個結構體,相當于s1是一個新的結構體,修改s1的high為10后,s的age仍然是8,s和s1互不影響。

    通過 lldb 調試, 也能夠看出 s 和 s1 是不同的結構體. 一個在 0x100008080, 一個在 0x100008098.

    swift

    復制代碼

    (lldb) frame variable -L s

    0x0000000100008080: (SwiftTest.Book) s = {

    0x0000000100008080:?? name = “程序員的自我修養”

    0x0000000100008090:?? high = 8

    }

    (lldb) frame variable -L s1

    0x0000000100008098: (SwiftTest.Book) s1 = {

    0x0000000100008098:?? name = “程序員的自我修養”

    0x00000001000080a8:?? high = 10

    }

    2、類是引用類型

    swift

    復制代碼

    class Person {

    ??? var age: Int = 22

    ??? var name: String?

    ??? init(_ age: Int, _ name: String) {

    ??????? self.age = age

    ??????? self.name = name

    ??? }

    ??? func eat(food:String) {

    ??????? print(“eat \(food)”)

    ??? }

    ??? func jump() {

    ??????? print(“jump”)

    ??? }

    }

    var c = Person(22, “jack”)

    var c1 = c

    c1.age = 30

    print(c.age, c1.age) // 30 30

    如果是類,c1=c的時候拷貝指針,產生了一個新的引用,但都指向同一個對象,修改c1的age為30后,c的age也會變成30。

    swift

    復制代碼

    (lldb) frame variable -L c

    scalar: (SwiftTest.Person) c = 0x0000000100679af0 {

    0x0000000100679b00:?? age = 30

    0x0000000100679b08:?? name = “jack”

    }

    (lldb) frame variable -L c1

    scalar: (SwiftTest.Person) c1 = 0x0000000100679af0 {

    0x0000000100679b00:?? age = 30

    0x0000000100679b08:?? name = “jack”

    }

    (lldb) cat address 0x0000000100679af0

    address:0x0000000100679af0, (String) $R1 = “0x100679af0 heap pointer, (0x30 bytes), zone: 0x7fff8076a000”

    通過lldb調試,發現類的實例 c 和 c1 實際上是同一個對象, 再通過自定義命令 address 可以得出這個對象是在 heap 堆上.

    而 c 和 c1 本身是2個不同的指針, 他們里面都存的是 0x0000000100679af0 這個地址.

    swift

    復制代碼

    (lldb) po withUnSAFePointer(to: &c, {print($0)})

    0x0000000100008298

    0 elements

    (lldb) po withUnSAFePointer(to: &c1, {print($0)})

    0x00000001000082a0

    0 elements

    延伸閱讀:

    二、SIL是什么

    Swift Intermediate Language,Swift高級中間語言,Swift 編譯過程引入SIL有以下優點:

    完全保留程序的語義既能進行代碼的生成,又能進行代碼分析處在編譯管線的主通道 (hot path)架起橋梁連接源碼與LLVM,減少源碼與LLVM之間的抽象鴻溝

    SIL會對Swift進行高級別的語意分析和優化。像LLVM IR一樣,也具有諸如Module,Function和BasicBlock之類的結構。與LLVM IR不同,它具有更豐富的類型系統,有關循環和錯誤處理的信息仍然保留,并且虛函數表和類型信息以結構化形式保留。它旨在保留Swift的含義,以實現強大的錯誤檢測,內存管理等高級優化。

    聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。

    猜你喜歡LIKE

    sql server2012r2所在服務器做端口限制,需要開放什么端口才能繼續訪問數據庫?

    2023-10-17

    Oracle有什么優勢和劣勢?

    2023-10-17

    CSS 隱藏頁面元素有哪些方法?

    2023-10-17

    最新文章NEW

    數據庫聚集索引非聚集索引實現上有哪些區別?

    2023-10-17

    開發web應用,好的開發流程是怎么樣的?

    2023-10-17

    為什么說Gradle是Android進階繞不去的坎?

    2023-10-17

    相關推薦HOT

    更多>>

    快速通道 更多>>

    最新開班信息 更多>>

    網友熱搜 更多>>