美文网首页鲸落消零派
Swift1-2引用类型与值类型

Swift1-2引用类型与值类型

作者: 浮华_du | 来源:发表于2021-04-10 14:38 被阅读0次

    之前我们介绍过Swift中class与Struct的区别,他们的本质区别其实就是类型的区别.(类是引用类型,结构体是值类型),下面我们仔细介绍一下引用类型与值类型.

    首先,我们知道内存(RAM)中有两个区域,栈区(stack)和堆区(heap).
    在 Swift 中,引用类型,存放在堆区;值类型,存放在栈区。(关于堆栈https://www.jianshu.com/p/924eaf8ffac4)

    通过代码测试可知:

    • 引用类型,即所有实例共享一份数据拷贝。(浅拷贝-影子)
    • 值类型,即每个实例保持一份数据拷贝。(深拷贝-克隆人)
      浅拷贝就是你的影子,深拷贝是你的克隆人

    引用类型

    import UIKit
    
    print("class=======")
    class TestClass{
        var a : Int = 0
        var b : String = ""
      
    }
    
    var t = TestClass()
    var t1 = t
    t1.a = 5
    print(t.a)//5
    print(t1.a)//5
    //在 Swift 中,可以使用以下方法来打印引用类型变量指向的内存地址。从中即可发现,两个变量指向的是同一块内存空间
    print("变量t内存地址----\(Unmanaged.passUnretained(t).toOpaque())")//变量t内存地址----0x0000600001f8e4f0
    print("变量t1内存地址----\(Unmanaged.passUnretained(t1).toOpaque())")//变量t1内存地址----0x0000600001f8e4f0
    //在 Swift 中,三等号(=== & !==)可以用来比较引用类型的引用(即指向的内存地址)是否一致。也可以在遵守 Equatable 协议后,使用双等号(== & !=)用来比较变量的内容是否一致。
    print("===比较变量内存地址----\(t==t1)")//===比较变量内存地址----true
    extension TestClass: Equatable {
        static func ==(left: TestClass, right: TestClass) -> Bool {
            return (left.a == right.a && left.b == right.b)
        }
    }
    print("==比较变量存储的内容----\(t==t1)")// ===比较变量内存地址----true
    
    
    引用类型堆栈.png

    值类型

    print("struct=======")
    struct TestStruct{
        var a : Int = 0
        var b : String = ""
        
    }
    
    var s = TestStruct(a: 0)
    var s1 = s
    s1.a = 5
    print(s.a)//0
    print(s1.a)//5
    //在 Swift 中,可以使用 withUnsafePointer(to:_:) 函数来打印值类型变量的内存地址,这样就能看出两个变量的内存地址并不相同。
    withUnsafePointer(to: &s) {
        print("变量s内存地址----\($0)")//变量s内存地址----0x000000011f285910
    }
    withUnsafePointer(to: &s1) {
        print("变量s1内存地址----\($0)")//变量s1内存地址----0x000000011f285928
    }
    
    //在 Swift 中,双等号(== & !=)可以用来比较变量存储的内容是否一致,如果要让我们的 struct 类型支持该符号,则必须遵守 Equatable 协议。
    extension TestStruct: Equatable {
        static func ==(left: TestStruct, right: TestStruct) -> Bool {
            return (left.a == right.a && left.b == right.b)
        }
    }
    print("==比较变量存储的内容----\(s==s1)")//==比较变量存储的内容----false
    
    值类型堆栈.png

    相关文章

      网友评论

        本文标题:Swift1-2引用类型与值类型

        本文链接:https://www.haomeiwen.com/subject/lstnkltx.html