iOS_struct与class的取舍

作者: Lin__Chuan | 来源:发表于2018-08-18 23:19 被阅读220次

Q: 究竟什么时该用struct, 什么时候用class呢?
A: 需要值语义的时候用struct, 需要引用语义的时候用class
A: 最普遍的情况是构建数据模型时用struct, 因为struct支持写时复制, 在性能上比class更好

Swift中的类型系统

image
  • 命名类型: protocol, enum, struct, class
  • 复合类型: tuple, function

至于这些基本类型:Bool,Int,UInt, Float, Double, Character, String, Array, Set, Dictionary, Optional。他们是通过命名类型创建的。

值语义与引用语义的区别

一个比较容易理解的方式是, 这两者存储数据的方式不同,

  • 对于值语义, 数据是直接保存在变量中,
  • 对于引用语义, 变量存储的是数据的引用地址.

在拷贝数据时, 对于值语义, 拷贝的是数据本身, 对于引用语义, 拷贝的是数据的引用地址

// struct
struct Person {
    var age = 10
}
var p = Person()
var p2 = p
printAddressForStruct(&p, &p2) 
p.age = 20
p2.age    // 10
printAddressForStruct(&p, &p2) 

// class
class PersonClass: NSObject {
    var age = 10
}
var pClass = PersonClass()
var pClass2 = pClass
printAddressForClass(pClass, pClass2)
pClass.age = 20
pClass2.age    // 20
printAddressForClass(pClass, pClass2)

在这里, 我们可以通过打印对象的内存地址来帮助分析
Swift中打印内存地址的方法如下: 这里打印struct的方法和class的方法不同, 唯一的区别是传入的参数不同, &objobj, 因为对于struct, 在拷贝数据的时候会开辟新的内存空间, 所以需要是直接取地址作为参数

// 打印struct的地址
func printAddressForStruct(_ values: UnsafeRawPointer...){
    values.forEach { (point) in
        // String(unsafeBitCast(point, to: Int.self), radix: 16)
        print(String(Int(bitPattern: point), radix: 16))
    }
    print("-----------------------")
}

// 打印class的地址
func printAddressForClass(_ values: Any...) {
    // 将地址转为16进制数
    values.forEach { (value) in
        print(String(unsafeBitCast(value as AnyObject, to: Int.self),radix: 16))
    }
    print("-----------------------")
}

// 打印class的地址2
func printAddress(_ values: Any...) {
    values.forEach { (value) in
        // 将class reference 转化 为pointer
        // 打印pointer 会直接打印内存地址
        print(Unmanaged.passUnretained(value as AnyObject).toOpaque())
    }
    print("-----------------------")
}

控制台输出

11c1bfef0   11c1bfef8
-----------------------
11c1bfef0   11c1bfef8

对于struct, 已经为数据开辟了新的内存

604000015550   604000015550
-----------------------
604000015550   604000015550

对于class, 拷贝数据时是引用地址的拷贝, 他们操作的一直是同一块内存空间, 所以数据是一样的.

参考自
何时用 struct?何时用 class?
swift - 在swift中,打印可变内存地址
Swift中Struct, Class and Enum 对比

相关文章

  • iOS_struct与class的取舍

    Q: 究竟什么时该用struct, 什么时候用class呢?A: 需要值语义的时候用struct, 需要引用语义的...

  • 项目管理

    理性与社交的取舍

  • 是借口?还是原因

    生活处处不选择,处处不取舍。 有的时候,不知是不敢做出选择与取舍,还是不会选择与取舍! 不敢,两难境地,理解! 不...

  • 热修复与插件化基础——dex与class

    一、dex/class浅析 1、class与dex对比 2、生成class与dex文件的指令 生成并运行class...

  • 一、经济学十大原理

    (1)人们面临权衡取舍 当人们组成社会的时候,他们便面临了不同的权衡取舍。最经典的取舍是在”大炮与黄油“之...

  • 于单向空间所想到的。

    生活,可以是在做取舍。 取舍好与坏,利与弊。 取舍,用他人的标准来衡量利益,衡量自己的拥有和存在。比他人好,便成功...

  • 2019-4-8随想:取舍

    取舍 今晚与友人讲论易理,由剥卦对取舍之道又有新的体悟。 其实剥本就有取舍之意。是要人能随时警醒自...

  • 关于RunTime运行时的小知识

    1.class_copyPropertyList与class_copyIvarList区别 class_copyP...

  • 权衡与取舍

    这两天楼下装修,电钻声一响,胖核桃就撕心裂肺的哭,看来这是目前他最最讨厌和害怕的声音了,越长大越要人一起玩,必须有...

  • 选择与取舍

    我们,总是贪婪,总想要的更多,总想轻而易举,总要不劳而获,期待着毫无阻碍就扶摇直上……然而,从一开始就注定了,快乐...

网友评论

    本文标题:iOS_struct与class的取舍

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