美文网首页
swift4 不同类型拷贝研究

swift4 不同类型拷贝研究

作者: AppleTTT | 来源:发表于2018-05-23 21:27 被阅读17次

最近在做内存优化的时候,发现了一些东西,记录一下;
我们经常会使用数组去存储数据,然后再控制器中使用,但是当我们共享数据的时候,我们经常会直接使用 = 操作来进行 赋值,这样的过程是一个深拷贝的过程,先有如下代码:

class Tree: NSObject {
    var name: String = "T"
    init(name: String) {
        self.name = name
    }
    
    override var description: String {
        return name
    }
}

class AAA {
    var arr: [Tree] = []
}

struct MMM {
    var t: Tree
    var description: String {
        return t.name
    }
}

func test() {

    let t1 = Tree.init(name: "1")
    let t2 = Tree.init(name: "2")
    let t3 = Tree.init(name: "3")
    
    let a = AAA.init()
    let b = a

    a.arr = [t1, t2, t3]
    print(a.arr,"---", b.arr)
    
    let t4 = Tree.init(name: "4")
    a.arr.append(t4)
    print(a.arr,"+++", b.arr)
    
    let t5 = Tree.init(name: name)
    let t6 = t5
    print("t5", address(of: t5))
    print("t6", address(of: t6))
    print("t5.name", address(of: t5.name),"t6.name", address(of: t6.name))
    t5.name = "newName"
    print("t5.newName", t5.name, address(of: t5.name),"t6.name", t6.name, address(of: t6.name))
    
    var m1 = MMM.init(t: t1)
    var m2 = MMM.init(t: t2)
    var m3 = MMM.init(t: t3)

    
    var mArr = [m1, m2, m3]
    var nArr = mArr
    var m4 = MMM.init(t: t4)
    nArr.append(m4)
    mArr.append(m1)
    
    print("pppppp",  mArr, nArr)
    
    print("mArr", address(of: &mArr))
    print("nArr", address(of: &nArr))

    print("mArr[0]", address(of: &mArr[0]))
    print("mArr[1]", address(of: &mArr[1]))
    print("mArr[2]", address(of: &mArr[2]))
    print("mArr[3]", address(of: &mArr[3]))
    
    print("nArr[0]", address(of: &nArr[0]))
    print("nArr[1]", address(of: &nArr[1]))
    print("nArr[2]", address(of: &nArr[2]))
    print("nArr[3]", address(of: &nArr[3]))
    
    print("m1", address(of: &m1))
    print("m2", address(of: &m2))
    print("m3", address(of: &m3))
    print("m4", address(of: &m4))
    
    print("mArr[0].t", address(of: &mArr[0].t))
    print("mArr[1].t", address(of: &mArr[1].t))
    print("mArr[2].t", address(of: &mArr[2].t))
    print("mArr[3].t", address(of: &mArr[3].t))
    
    print("nArr[0].t", address(of: &nArr[0].t))
    print("nArr[1].t", address(of: &nArr[1].t))
    print("nArr[2].t", address(of: &nArr[2].t))
    print("nArr[3].t", address(of: &nArr[3].t))
    
}

func address<T: AnyObject>(of object: T) -> String {
    let addr = unsafeBitCast(object, to: Int.self)
    return String(format: "%p", addr)
}
    
func address(of object: UnsafeRawPointer) -> String {
    let addr = Int(bitPattern: object)
    return String(format: "%p", addr)
}

记录结果如下:

[1, 2, 3] --- [1, 2, 3]
[1, 2, 3, 4] +++ [1, 2, 3, 4]
t5 0x1d022e400
t6 0x1d022e400
t5.name 0x1d04598e0 t6.name 0x1d04598e0
t5.newName newName 0x1d04598e0 t6.name newName 0x1d04598e0
pppppp [AAA.MMM(t: 1), AAA.MMM(t: 2), AAA.MMM(t: 3), AAA.MMM(t: 1)] [AAA.MMM(t: 1), AAA.MMM(t: 2), AAA.MMM(t: 3), AAA.MMM(t: 4)]
mArr 0x1d00948e0
nArr 0x1d0094890
mArr[0] 0x16faed4f8
mArr[1] 0x16faed4f0
mArr[2] 0x16faed4e8
mArr[3] 0x16faed4e0
nArr[0] 0x16faed4d8
nArr[1] 0x16faed4d0
nArr[2] 0x16faed4c8
nArr[3] 0x16faed4c0
m1 0x16faed558
m2 0x16faed550
m3 0x16faed548
m4 0x16faed530
mArr[0].t 0x16faed4b8
mArr[1].t 0x16faed4b0
mArr[2].t 0x16faed4a8
mArr[3].t 0x16faed4a0
nArr[0].t 0x16faed498
nArr[1].t 0x16faed490
nArr[2].t 0x16faed488
nArr[3].t 0x16faed480

总结:

1. 数组赋值是深拷贝的过程,因为是值类型;类是浅拷贝,因为类是引用类型;
2. 当我们在类里面有值类型的变量的时候,进行拷贝,拷贝的两个对象(t5 和 t6)的地址以及值类型变量(t5.name 和 t6.name)的地址都是一样的,如果改变一个对象的值类型变量,两个对象(t5.name 和 t6.name)的都会被改变;
3. 值类型有值类型的变量的时候,复制是深复制,mArr 还有 nArr 以及其数组内的内容都不一样

此次获取地址来自喵神的 gist
自己之前找的打印地址的方法都不对,在 swift4 中使用此法可以正确打印地址

相关文章

  • swift4 不同类型拷贝研究

    最近在做内存优化的时候,发现了一些东西,记录一下;我们经常会使用数组去存储数据,然后再控制器中使用,但是当我们共享...

  • 使用BeanUitls提高对象拷贝效率

    对象拷贝 对象拷贝分为深拷贝和浅拷贝。根据使用场景进行不同选择。在Java中,数据类型分为值类型(基本数据类型)和...

  • JavaScript中的浅拷贝和深拷贝

    浅拷贝 浅拷贝是处理栈内存。 不同形式的浅拷贝示例: 基本类型如果是基本类型:number、string、bool...

  • 深拷贝和浅拷贝

    浅拷贝就比如像引用类型,而深拷贝就比如值类型。浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不...

  • 第二月第四周

    深拷贝是对于一个对象所有层次的拷贝(递归) 浅拷贝对不可变类型和可变类型的copy不同* is 是比较两个引用是否...

  • JavaScript面试考点之深拷贝和浅拷贝

    1、数据类型 说起拷贝,就不得不提起js的数据类型了,因为深拷贝和浅拷贝的核心就在于不同的数据类型在内存中存储的地...

  • Java深拷贝和浅拷贝

    定义 浅拷贝 基本数据类型 拷贝数值 引用类型 拷贝对象引用 深拷贝 基本数据类型 拷贝数值 引用类型 拷贝引用所...

  • 自定义开发-对象属性拷贝

    1,工具类的特征 完成基本的属性复制功能; 不同类型的属性赋值,比如常见的基本类型与包装类型; 深拷贝和浅拷贝,注...

  • Python的深拷贝和浅拷贝

    拷贝:创建一个具有相同类型和相同值的变量,但是二者地址不同。 浅拷贝 浅拷贝:只拷贝父对象,不会拷贝内部的子对象。...

  • 深拷贝与浅拷贝的实现(一)

    最近的学习中,仔细研究了下深拷贝和浅拷贝,下面就来简单的总结下。 数据类型 首先我们了解下两种数据类型: 1、基本...

网友评论

      本文标题:swift4 不同类型拷贝研究

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