在Swift中classstruct关系其实很简单,类似UIViewCALayer,我们知道类class的本质就是结构体,所以说结构体struct相比较类class更加轻量级,因为类的功能比结构体多很多

结构体struct是值类型,类class是引用类型 通过一个示例来演示值类型与引用类型,数据之间的传递

一.引用类型模型数据传递示例

// 定义一个模型类,用来存放数据
class Model: NSObject {
    var age: Int = 0
}
// 在控制器A中
class ViewController: UIViewController {

    var model: Model = Model()
    
    @IBAction func jumpAction(_ sender: UIButton) {
        let vc = DetailController()
        vc.model = self.model
        self.navigationController?.pushViewController(vc, animated: true) 
    }
    // 打印当前模型的值和地址
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(model.age)
        print(model)
    }
}    

在控制器B中

class DetailController: UIViewController {

    var model: Model?
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let models = model {
            models.age = models.age + 1
            print(models.age)
            print(models)
        }
    }    

问题

跳转到控制器B中,点击屏幕model.age+1,那么age由最初的0变成1,那么返回控制器A,点击屏幕此时model.age是什么呢?当model是class类型时候,此时是引用类型,那么我们在控制器B操作的模型数据实际上就是对控制器A中的model的操作,这就是引用类型,引用的对象是同一个

struct Model {
    var age: Int = 0
}

如果model修改为结构体类型,那么在控制器B中,这段代码就会报错 demo

报错很明显,因为这里model使用了let修饰,结构体model变成了常量,model.age也变成了常量

需要修改为如下

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    model!.age = model!.age + 1
    print(model!.age)
    print(model)
}

当我们再次点击控制器B的屏幕,可以看到输出1,2,3,返回控制器A,打印当前model.age值仍然是0. 通过这个示例,如果model是引用类型,那么是地址传递,查看地址一模一样

结构体指针的打印查看

// 在控制器A中
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print(model.age)
    let userPointer =  withUnsafePointer(to: &model, {$0})
    print(userPointer)
}    
0
0x00007f9ebcd07de0

// 在控制器B中
1
0x00007f9ebcd1efd0

显而易见,指针地址都不同,这样就证明了类class是地址传递,结构体struct是值传递

二.类和结构体的不同点

三.什么时候用结构体

官方建议:

define a class, and create instances of that class to be managed and passed by reference. 
In practice, this means that most custom data constructs should be classes, not structures.

虽然官方建议尽量使用类而不是结构体,因为类更加灵活,使用更加方便,可以说结构体有的功能类都可以实现,类有些功能结构体无法实现

由于结构体更加轻量级,性能略好点(1.占用内存更少;2.创建结构体实例速度更快),所以在项目实际使用的时候优先虑使用结构体(特别是数据量比较大的时候),当发现结构体无法满足项目需求的时候,才更改使用类

参考:酷走天涯: Swift3.0 - 类和结构体的区别