Swift中的内存管理

一、内存分配

  值类型,比如说枚举和结构体,它们的内存分配和管理都十分简单。当你新建一个值类型实例时,系统会自动为实例分配大小合适的内存。任何传递实例的操作,比如说作为参数传递给函数,以及存储到属性的操作,它们都会创建实例的副本。当实例不再存在时,Swift会回收内存。因此,我们不需要做任何事情来管理值类型的内存。

  在Swift中,内存管理这个议题,通常都是和引用类型,尤其是类相关的。跟值类型一样,当我们新建类实例时,系统会为实例分配内存空间。但是,和值类型所不同的是,当我们把类实例作为参数传递给函数,或者将其存储到属性中时,不再是复制实例本身,而是对同一块内存创建新的引用。对于同一块内存拥有多个引用的情况,这意味着,只要其中任何一个引用修改了类的实例,那么所有的引用都将能看到这个变化的结果。

  和C语言不同,Swift并不需要我们手动的管理内存,系统会自动为每个类实例维护一个引用计数(Reference Count)。只要引用计数大于0,实例就会一直存在;一旦引用计数变为0,实例就会被销毁,而它所占用的内存就会被回收,此时deinit方法就会被调用。因此,我们可以通过实现deinit方法来追踪实例是否被销毁。

二、循环引用

  在正式演示循环引用之前,我们先通过一个简单的例子来观察一下类实例从创建到最后被销毁的全过程:

class Person: CustomStringConvertible {

    let name: String

    // 遵守CustomStringConvertible协议,实现
    // description计算属性,自定义打印格式
    var description: String {
        return "\(name)"  // "Person(\(name))"
    }

    // 构造函数
    init(name: String) {

        // 初始化私有属性
        self.name = name
    }

    // 当引用计数为0时,这个方法会被调用
    deinit {
        print("\(self)被销毁了")
    }
}

// 创建一个Person实例,并且对其进行初始化
// 这里需要将实例变量james声明为可选类型,
// 这样后面就可以给它赋值nil,从而方便调用
// deinit方法
var james: Person? = Person(name: "James")
print("创建了一个Person类实例\(james!)")

// 默认情况下,所有的引用都是强引用,这意味着当我们创建
// Person实例james,并且给它赋值James时,引用计数是
// 加1的。当我们再次给james赋值为nil时,引用计数是减1
// 的,这样一来,deinit方法就会被调用,我们就能看到打印
james = nil

  程序运行之后,我们首先会看到Person实例james被创建,并且当我们将其重置为nil时,它就会被销毁(deinit方法被调用):

一个类实例从创建到销毁的全过程.png

  接下来,我们要修改程序。假设James是一位资深的爱宠人士,它最近买了一条宠物狗,名字叫做旺财。我们先创建一个Dog类,然后再对上面的代码进行修改:

// Dog.swift
class Dog: CustomStringConvertible {

    let name: String
    var owner: Person?

    // 自定义输出格式
    var description: String {
        if let dogOwner = owner {
            return "\(name)的主人是\(dogOwner)."
        } else {
            return "\(name)是一条流浪犬。"
        }
    }

    // 构造函数
    init(name: String) {

        // 初始化私有属性
        self.na
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值