Swift ARC机制以及弱引用的使用

  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”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值