Swift使用自动引用计数(ARC)来管理应用程序的内存使用。当实例不再被需要时,由ARC自动释放内存。swift ARC的机制通过编译器实现,和java的gc垃圾回收机制不一样。
每当创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息。ARC对每个类实例,都追踪有多少属性、常量、变量指向这些实例。当有活动引用指向它时,ARC是不会释放这个实例的。当实例不再被使用时,ARC会释放实例所占用的内存,这些内存可以再次被使用。
下面的测试程序,testARC1 内存释放比函数结束先进行,说明在引用计数为0时,内存会立即释放。testARC2,说明在存在循环引用时,使用弱引用可以防止内存泄漏,因为弱引用并不保持对所指对象的强烈持有,因此并不阻止ARC对引用实例的回收。指明弱引用需添加weak关键字。
具体代码:
- //
- // main.swift
- // ARCTest
- //
- // Created by 凌云 on 16/1/12.
- // Copyright © 2016年 凌云. All rights reserved.
- //
-
- import Foundation
-
- class Teacher
- {
- var storeName:String //存储属性
- var name:String{//计算属性
- get{
- return self.storeName
- }
- set{
- self.storeName = newValue//便捷setter声明
- }
- }
-
- var student: Student?//可选类型不用在init函数中初始化
-
- init(name:String)
- {
- storeName = name
- print("老师\(self.name)实例初始化完成")
- }
-
- deinit
- {
- print("老师\(name)实例内存释放")
- }
-
- func teaching()
- {
- print("老师\(name)正在讲课")
- }
- }
-
- class Student
- {
- var storeName:String //存储属性
- var name:String{//计算属性
- get{
- return self.storeName
- }
- set{
- self.storeName = newValue//便捷setter声明
- }
- }
-
- weak var teacher: Teacher? //弱引用,解决相互引用导致的内存泄露问题
-
- init(name:String)
- {
- storeName = name
- print("学生\(self.name)实例初始化完成")
- }
-
- deinit
- {
- print("学生\(name)实例内存释放")
- }
-
- func learning()
- {
- print("学生\(name)正在听课")
- }
-
- }
-
- func testARC1()
- {
- var teacher:Teacher? = Teacher(name:"张先生")//使用可选类型以后面赋值为nil
- var teacher2:Teacher? = teacher
- var teacher3:Teacher? = teacher2
- teacher?.teaching()
- teacher2?.teaching()
- teacher3?.teaching()
-
- teacher = nil
- teacher2 = nil
- teacher3 = nil//第三个引用对象为nil,此时已无引用,arc回收,实例释放
-
- print("\(teacher?.teaching())")//可选类型,已释放调用也不会崩溃
-
- print("test arc1 end.")
- }
-
- func testARC2()
- {
- var teacher:Teacher? = Teacher(name:"Zhang先生")
- var student:Student? = Student(name:"Xiao学生")
- teacher?.teaching()
- student?.learning()
-
- teacher?.student = student
- student?.teacher = teacher
-
- teacher = nil
- student = nil
-
- print("test arc2 end.")
- }
-
- testARC1()
- testARC2()
- print("程序结束.")
运行结果:
老师张先生实例初始化完成
老师张先生正在讲课
老师张先生正在讲课
老师张先生正在讲课
老师张先生实例内存释放
nil
test arc1 end.
老师Zhang先生实例初始化完成
学生Xiao学生实例初始化完成
老师Zhang先生正在讲课
学生Xiao学生正在听课
老师Zhang先生实例内存释放
学生Xiao学生实例内存释放
test arc2 end.
程序结束.
可以看到,testARC2在存在循环引用的情况下,仍然成功的进行了内存释放。
参考资料:
[1]: http://www.jb51.cc/article/p-xavxdsmc-dy.html“fengsh998”