美文网首页IOS理论知识
Swift结构体和类详解

Swift结构体和类详解

作者: WSJay | 来源:发表于2018-12-06 23:57 被阅读119次

    一、类和结构体的对比

    (一)、类和结构体的相同点
    • 定义存储值的属性;
    • 定义提供功能的方法;
    • 定义下标以使用下标语法提供对其值的访问;
    • 定义初始化器来设置其初始状态;
    • 通过扩展增加新功能;
    • 遵守协议来提供某种标准功能;
    (二)、类和结构体的不同点

    类具有结构体不具备的其他功能:

    • 继承使一个类可以继承另一个类的特性;
    • 类型转换使你可以在运行时检查和解释类实例的类型;
    • 析构器使类的实例可以释放它已分配的任何资源;
    • 引用计数器允许对一个类实例的多个引用;
    (三)、如何选择类和结构体

    在应用程序中存储数据和建模行为时,结构和类是很好的选择,但是它们的相似性使得很难正确选择使用哪种数据类型。
    考虑以下建议,可以帮助你在向应用程序中添加新数据类型时选择合适的数据类型。

    • 默认情况下使用结构;
    • 在需要Objective-C互操作性时使用类;
    • 当您需要控制正在建模的数据的标识时,请使用类;
    • 使用结构体和协议通过共享实现来采用行为;
      参考资料:
    • 如何选择类和结构体

    二、定义语法

    类和结构体的定义语法:

    struct SomeStructure {
        // structure definition goes here
    }
    class SomeClass {
        // class definition goes here
    }
    

    定义类和结构体的示例:

    struct Resolution {
        var width = 0
        var height = 0
    }
    class VideoMode {
        var resolution = Resolution()
        var interlaced = false
        var frameRate = 0.0
        var name: String?
    }
    

    二、结构体的全能初始化器

    所有结构都有一个自动生成的成员初始化器,可以使用它初始化新结构实例的所有成员属性。

    let vga = Resolution(width: 640, height: 480)
    

    与结构不同,类实例不接收默认的全能初始化器。

    三、结构体和枚举是值类型

    值类型是一种类型,其值在被赋值给变量或常量时被复制,或者在传递给函数时被复制。
    Swift中的所有的基本类型:整数、浮点数、布尔、字符串、 数组 和 字典都是值类型,并且在底层的实现是结构体。同时Swift中所有的枚举和结构体也是值类型,这意味着我们创建的任何结构和枚举实例,以及作为它们属性的任何值类型,在代码中传递时始终会被复制。

    注意:标准库中定义的集合(如数组,字典和字符串)使用了优化来降低复制时的性能消耗。 这些集合不是立即复制,而是共享内存,其中元素存储在原始实例和任何副本之间。 如果修改了这个集合的其中一个副本,则在修改之前复制元素。 你在代码中看到的行为总是好像立即发生了复制。

    let hd = Resolution(width: 1920, height: 1080)
    var cinema = hd
    cinema.width = 2048
    print("cinema is now \(cinema.width) pixels wide")
    // Prints "cinema is now 2048 pixels wide"
    
    print("hd is still \(hd.width) pixels wide")
    // Prints "hd is still 1920 pixels wide"
    
    

    上述示例中,首先声明了一个常量hd,将其设置为一个Resolution类型的结构体实例。然后又声明了一个变量cinema,将其设置为hd当前的值。由于Resolution是一个结构体类型,因此会生成该实例的副本,并将新的副本分配给cinema。尽管hdcinema现在有相同的widthheight,但是在内存中它们是两个完全不同的实例。因此当修改cinema中的width属性时,对hd中的width属性并没有影响。它们在内存中的分配如下图所示:

    sharedStateStruct_2x.png

    同理,枚举也是相同的。

    enum CompassPoint {
        case north, south, east, west
        mutating func turnNorth() {
            self = .north
        }
    }
    var currentDirection = CompassPoint.west
    let rememberedDirection = currentDirection
    currentDirection.turnNorth()
    
    print("The current direction is \(currentDirection)")
    print("The remembered direction is \(rememberedDirection)")
    // Prints "The current direction is north"
    // Prints "The remembered direction is west"
    

    四、类是引用类型

    与值类型不同,引用类型在分配给一个变量或常量,或者传递给函数时不会被拷贝。 不是使用拷贝的对象,而是使用对同一个现有实例对象的引用。

    let tenEighty = VideoMode()
    tenEighty.resolution = hd
    tenEighty.interlaced = true
    tenEighty.name = "1080i"
    tenEighty.frameRate = 25.0
    
    let alsoTenEighty = tenEighty
    alsoTenEighty.frameRate = 30.0
    
    print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
    // Prints "The frameRate property of tenEighty is now 30.0"
    

    上述示例中,由于类是引用类型,tenEightyalsoTenEighty都引用相同的VideoMode实例对象。实际上,它们只是同一个实例对象的两个不同名称,如下图所示:

    sharedStateClass_2x.png

    五、相等性判断

    因为类是引用类型,所以多个常量和变量在内存中可能引用的是同一个类的实例对象。 而对于结构和枚举来说情况并非如此,因为它们在分配给常量或变量或传递给函数时总是被复制。
    有时可以判断两个常量或变量是否指向同一个类的相同实例对象。 为了实现这一点,Swift提供了两个身份运算符:

    • 相同的 (===)
    • 不完全相同(!==)
      使用这些运算符可以检查两个常量或变量是否引用同一个实例对象:
    if tenEighty === alsoTenEighty {
        print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
    }
    // Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance."
    

    ===并不等同于 =====意味着class类型的两个常量或变量引用完全相同的类实例对象。而==意味着两个实例在值上被认为是相等的或等价的,对于相等的某些适当含义,由类型的设计者定义。
    当自定义结构和类时,你有责任确定两个实例相等的条件。 在等价运算符中描述了定义自己的“等于”和“不等于”运算符的实现的过程。 Equivalence Operators

    六、指针

    如果你熟悉C,C ++或Objective-C,你可能知道这些语言都使用指针来引用内存中的地址。 Swift中的常量或变量对某个引用类型的实例的引用,类似于C中的指针,但是它不是指向内存中地址的直接指针,并且也不需要你使用星号(*)来指明正在创建一个引用。 相反,这些引用的定义与Swift中的任何其他常量或变量一样。 标准库提供了指针和缓冲区类型,如果需要直接与指针交互,可以使用这些类型- 请参阅手动内存管理

    七、其他专题模块

    Swift 4.2 基础专题详解

    相关文章

      网友评论

        本文标题:Swift结构体和类详解

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