美文网首页
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 不同类型拷贝研究

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