iOS之swift中的引用类型

425 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

类的常用写法

//****** 写法一 *******
class CJLTeacher {
    var age: Int = 18
    
    func teach(){
        print("teach")
    }
    init(_ age: Int) {
        self.age = age
    }
}
var t = CJLTeacher.init(20)

//****** 写法二 *******
class CJLTeacher {
    var age: Int?
    
    func teach(){
        print("teach")
    }
    init(_ age: Int) {
        self.age = age
    }
}
var t = CJLTeacher.init(20)

在类中,如果属性没有赋值,也不是可选项,编译会报错

2.1.jpg

为什么类是引用类型?

定义一个类,通过一个例子来说明

class CJLTeacher1 {
    var age: Int = 18
    var age2: Int = 20
}
var t1 = CJLTeacher1()

类初始化的对象t1,存储在全局区

  • 打印t1、t:po t1,从图中可以看出,t1内存空间中存放的是地址,t中存储的是

2.2.jpg

获取t1变量的地址,并查看其内存情况

  • 获取t1指针地址:po withUnsafePointer(to: &t1){print($0)}
  • 查看t1全局区地址内存情况:x/8g 0x0000000100008218
  • 查看t1地址中存储的堆区地址内存情况:x/8g 0x00000001040088f0

2.3.jpg

引用类型 特点

  • 1、地址中存储的是堆区地址
  • 2、堆区地址中存储的是

问题1:此时将t1赋值给t2,如果修改了t2,会导致t1修改吗?

  • 通过lldb调试得知,修改了t2,会导致t1改变,主要是因为t2t1地址中都存储的是 同一个堆区地址,如果修改,修改是同一个堆区地址,所以修改t2会导致t1一起修改,即浅拷贝

2.5.jpg

问题2:如果结构体中包含类对象,此时如果修改t1中的实例对象属性,t会改变吗?

代码如下所示

class CJLTeacher1 {
    var age: Int = 18
    var age2: Int = 20
}

struct CJLTeacher {
    var age: Int = 18
    var age2: Int = 20
    var teacher: CJLTeacher1 = CJLTeacher1()
}

var  t = CJLTeacher()

var t1 = t
t1.teacher.age = 30

//分别打印t1和t中teacher.age,结果如下
t1.teacher.age = 30 
t.teacher.age = 30

从打印结果中可以看出,如果修改t1中的实例对象属性,会导致t中实例对象属性的改变。虽然在结构体中是值传递,但是对于teacher,由于是引用类型,所以传递的依然是地址

同样可以通过lldb调试验证

  • 打印t的地址:po withUnsafePointer(to: &t){print($0)}
  • 打印t的内存情况: x/8g 0x0000000100008238
  • 打印t中teacher地址的内存情况:x/8g 0x000000010070e4a0

2.6.jpg 注意:在编写代码过程中,应该尽量避免值类型包含引用类型