2019最新iOS面试(OC+swift)

iOS_struct与class的取舍

2018-08-18  本文已影响220人  Lin__Chuan

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

Swift中的类型系统

image

至于这些基本类型: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 对比

上一篇 下一篇

猜你喜欢

热点阅读