Swift-深浅拷贝与内存管理(高级)
/*
Swift内存管理(高级部分)
*/
import Foundation
/*
1、深浅拷贝
*/
print("1、深浅拷贝")
//结构体,值类型
struct Deep{
var copy:Int = 0
}
//类,引用类型
class Shallow{
var copy:Int = 0
}
//深拷贝:内容相同,对象不同(给d1分配一块新内存,将d0的内容赋给d1)
//值类型的赋值操作是深拷贝
var d0 = Deep()
var d1 = d0
d1.copy = 8
print(d0.copy)
print(d1.copy)
//引用类型的赋值操作是浅拷贝(将不同的引用指向同一个对象)
var s0 = Shallow()
var s1 = s0
s1.copy = 6
print(s0.copy)
print(s1.copy)
/*
2、字符串拷贝
*/
print("\n2、字符串拷贝")
var str:String = "Hello" //String--结构体(值类型),因此String操作是深拷贝
var str1 = str
str1 += ",ming"
print(str)
print(str1)
var mutStr = NSMutableString(string:"mutable") //NSMutableString--类(引用类型),因此NSMutableString操作是浅拷贝
var mutStr1 = mutStr
mutStr1.insert(",string", at: mutStr.length)
print(mutStr)
print(mutStr1)
/*
3、集合类拷贝
*/
print("\n3、集合类拷贝")
var array:Array<Int> = [1,2,3] //Array--结构体(值类型)
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 mutArray = NSMutableArray(array:[1,2,3])
var mutArray1 = mutArray
mutArray1.add(4)
print(mutArray)
print(mutArray1)
//总结:OC中类型(Foundation框架下)在Swift中都是class类型(引用类型),而Swift原生的都是使用结构体实现
/*
4、集合类拷贝深入分析
*/
print("\n4、集合类拷贝深入分析")
var de0 = Deep()
var de1 = Deep()
//此数组的元素都是值类型
var deArray = [de0,de1]
var sh0 = Shallow()
var sh1 = Shallow()
//此数组的元素都是引用类型
var shArray = [sh0,sh1]
//深拷贝
var deArray1 = deArray
var shArray1 = shArray
//将数组中某个元素替换或者改变数组大小,不会影响另一个数组
deArray1.removeLast()
//deArray1[0] = Deep(copy:2)
//print(deArray[0].copy)
//print(deArray1[0].copy)
//(1)根据被拷贝数组的大小来创建一个新的数组对象,新的容量跟原始数组大小相同
//(2)将原始数组中的每一个元素依次拷贝到新的数组对象中
deArray1[0].copy = 20
print(deArray[0].copy)
print(deArray1[0].copy)
shArray1[0].copy = 30
print(shArray[0].copy)
print(shArray1[0].copy)
/*
5、隐式强引用
*/
print("\n5、隐式强引用")
class Student {
var name:String
init(name:String) {
self.name = name
}
func show() {
print("name=\(name)")
}
deinit {
print("\(name) deinit")
}
}
//此时,stu0和stu1都引用了同一个对象
var stu0:Student? = Student(name:"Tom")
var stu1 = stu0
stu0 = nil
stu1 = nil
//对象加入数组中,对象如果使引用数据类型,那么数组会强引用该对象(即数组让该对象的引用计数+1)
var stuArray = [Student(name:"san"),Student(name:"si")]
stuArray[0].name = "zhangsan"
//(1)当某个对象不再属于数组时,该对象引用计数-1
//数组本身被销毁时,它包含的所有对象不再属于它,因此如果数据是引用数据类型,它的引用计数将会-1
stuArray.remove(at: 0)
/*
6、局部和全局引用
(1)作用域(2)生命周期
*/
print("\n6、局部和全局引用")
/*
7、闭包属性引起的循环强引用
*/
print("\n7、闭包属性引起的循环强引用")
class CycleRef{
var a:Int = 8
//如果闭包属性中没有直接或间接访问self,就不会产生循环引用
lazy var clouser: ()->Void = {
// print("clouser")
//默认闭包会对它访问的对象执行强引用
[unowned self] in //使用unowned使其变为弱引用
print("a=\(self.a)") //或以下方法
// [weak self] in
// print("a=\(self!.a)")//使用weak可能存在self为空时,需要对其进行解包或者判空,一般使用unowned居多
}
deinit {
print("deinit")
}
}
var cr:CycleRef? = CycleRef()//引用计数+1
//前提:闭包或者函数是引用数据类型
cr!.clouser() //引用计数+()? 闭包强引用了对象,对象调用闭包,循环引用
cr = nil //引用计数-1