/*
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
Swift 基础学习(内存管理二)
最新推荐文章于 2024-04-26 08:41:21 发布