Swift 基础学习(内存管理二)

/*
    Swift内存管理第二部分(高级)
(1)深浅拷贝
(2)字符串拷贝
(3)集合类的拷贝
(4)局部临时对象和全局对象
(5)类型属性的声明周期
(6)隐式强引用-集合类,timer/元组
(7)闭包属性引起的循环引用
(8)解决(7)的问题
*/

/*
(1)
*/
//结构体,值类型
struct Deep {
    var copy: Int = 0
}
//类,引用类型
class Shallow {
    var copy: Int = 0
}

//值类型的赋值操作是深拷贝
var d0 = Deep()
//深拷贝
//系统会分配一块内存与d1进行绑定,也就是说d1指向这块内存,这块内存的内容等于d0指向的内存的内容,二者只是内容相同而已,但分别指向不同的内存
var d1 = d0
d1.copy = 9
//值不一样就说明是两份不同的拷贝,打印结果为d0.copy为0,d1.copy为9
print(d0.copy)
print(d1.copy)

//引用类型的赋值操作是浅拷贝
//可能存在的问题:当多份引用同时指向一个对象时,如果对象提前释放,就会出现内存泄露
var s0 = Shallow()
//浅拷贝
var s1 = s0
s1.copy = 9
//打印结构都是9
print(s0.copy)
print(s1.copy)


/*
(2)字符串拷贝
*/
var swiftStr: String = "Hello"
var swiftStr1 = swiftStr
swiftStr1 += "World"
//swiftStr1的变化如果会引起swiftStr变化就是浅拷贝,结构发现是深拷贝;简单的方法我们可以直接看他们的类型
print(swiftStr)
print(swiftStr1)

//浅拷贝
var ocStr = NSMutableString(string: "Hello")
var ocStr1 = ocStr
ocStr1.insertString("World", atIndex: ocStr.length)
print(ocStr)
print(ocStr1)

/*
(3)集合类的拷贝
*/
//深拷贝
var array: Array<Int> = [1,2,3]
var array1 = array
array1 += [4,5,6]
print(array)
print(array1)

//深拷贝
var dict: Dictionary<Int, String> = [1:"a",2:"b"]
var dict1 = dict
dict1[3] = "c"
print(dict)
print(dict1)

//浅拷贝
var ocArray = NSMutableArray(array: [1,2,4])
var ocArray1 = ocArray
ocArray1.addObject(3)
print(ocArray)
print(ocArray1)

/*
(4)深入分析集合类的拷贝
//结构体,值类型
struct Deep {
var copy: Int = 0
}
//类,引用类型
class Shallow {
var copy: Int = 0
}
*/
var de0 = Deep()
var de1 = Deep()
//数组的元素都是值类型
var dearray = [de0,de1]

var sh0 = Shallow()
var sh1 = Shallow()
//数组的元素都是引用类型
var shaarray = [sh0, sh1]

//深拷贝
var dearray1 = dearray
var sharray1 = shaarray

/*
//当将数组中的某个元素替换,或者改变数组的大小,不会影响另外一个数组
dearray1.removeLast()
print(dearray1.count)
print(dearray.count)

dearray1[0] = Deep(copy: 3)
print(dearray1[0].copy)
print(dearray[0].copy)
*/

//(1)根据被拷贝数组的大小来创建一个新的数组对象,新的容量跟原始数组大小相同
//(2)将原始数组中的每一个元素依次拷贝到新的数组对象中
dearray1[0].copy = 88
print(dearray[0].copy)
print(dearray1[0].copy)

sharray1[0].copy = 99
print(shaarray[0].copy)
print(sharray1[0].copy)

/*
(5)隐式强引用
*/
class Student {
    var name: String
    init(name: String) {
        self.name = name
    }
    func show() {
        print("name = \(name)")
    }
    deinit {
        print("\(name) deinit!")
    }
}
//此时,stu0和stru1都引用了同一个对象
var stu0: Student? = Student(name: "Tom")
var stu1 = stu0
stu0 = nil
stu1 = nil

//Student(name: "zhangsan")
//Student(name: "lisi")
//对象加入到数组中,对象如果引用数据类型,那么数组会强引用该对象
//数组让该对象的引用计数加1
var stuarray: [Student]? = [Student(name: "zhangsan"), Student(name: "lisi")]
//(1)当某个对象不再属于数组时,该对象的引用计数会减1
//(2)数组本身被销毁的时候,它包含的所有对象不再属于它,因此如果对象是引用数据类型,它的计数将会减1
//stuarray.removeAtIndex(0)
stuarray = nil

/*
(6)局部和全局引用
*/
//1.作用域 2.生命周期
//let ref: Int = Int(5)

if true {
    var ref: Student = Student(name: "xiaocui")
}

//全局引用作用域:定义的位置开始到文件的结尾处
var gloabal_ref = Int(8)
gloabal_ref = 10

//生命周期: 跟当前程序的生命周期相同
func testFunc() {
    gloabal_ref = 10
}

/*
(7)闭包属性引起的循环引用
*/
class CycleRef {
    var a: Int = 9
    //如果闭包属性中没有直接或者间接访问self,就不会产生循环强引用
    lazy var closure:() ->Void = {
        //默认闭包会对它访问的对象执行强引用
//        [unowned self] in //解决方法
//        print("a=\(self.a)")

        //等同于
        [weak self] in
        print("a = \(self!.a)")
    }
    deinit {
        print("deinit")
    }
}
//两个对象,闭包对象,cr指向的对象
//前提:闭包或者函数是引用数据类型.
var cr: CycleRef? = CycleRef()//引用计数:+1
cr!.closure()//引用计数: +1或+2...
cr = nil // -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值