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://blog.csdn.net/fengsh998/article/details/31824179 “fengsh998”