我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Swift 列举内存管理与异常处理具体代码

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Swift 列举内存管理与异常处理具体代码

1. Swift 内存销毁时机


// Swift5 内存销毁时机
// 引用类型的内存销毁时机
class ClassDemo {
    var a = "value a"
    deinit {
        // 实例被释放
        print("deinit class a")
    }
}

// 可空类型
var ins1: ClassDemo? = ClassDemo()
var ins2 = ins1
var ins3 = ins2

ins1 = nil // 取消 ins1 引用
ins2 = nil // 取消 ins2 引用
print(String(describing: ins3?.a)) // 此处 ins3 引用的实例依然在,Optional("value a")

// 对实例引用被全部取消,ClassA 实例此处才销毁
ins3 = nil // deinit class a

2. Swift 单向引用


// Swift5 单向引用
class ClassA {
    
    deinit {
        print("deinit ClassA")
    }
    
    func foo() {
        print("func foo in ClassA")
    }
}

class ClassB {
    // 此处引用 ClassA 的实例
    var ins: ClassA?
    
    init(ins: ClassA?) {
        self.ins = ins
    }
    
    deinit {
        print("deinit ClassB")
    }
}

var clzA: ClassA? = ClassA()
var clzB: ClassB? = ClassB(ins: clzA)

// 此处 clzA 所引用的内存并未释放
clzA = nil
// 依然可以调用 clzB 中的 clzA 实例的 foo 方法
clzB?.ins?.foo() // func foo in ClassA
// 此时 ClassB 实例被释放,不再有引用指向 ClassA 随即所占内存也被释放
clzB = nil // deinit ClassB \n deinit ClassA

3. Swift 循环引用


// Swift5 循环引用
class ClassC {
    var insD: ClassD?
    
    deinit {
        print("deinit ClassC")
    }
    
    func foo() {
        print("func foo in ClassC")
    }
}

class ClassD {
    // 此处引用 ClassC 的实例
    var insC: ClassC?
    
    init(ins: ClassC?) {
        self.insC = ins
    }
    
    deinit {
        print("deinit ClassD")
    }
}

var clzC: ClassC? = ClassC()
var clzD: ClassD? = ClassD(ins: clzC)

clzC?.insD = clzD

// 此处 clzC 所引用的内存并未释放,对应实例被 clzD 的 insC 引用
clzC = nil
// 依然可以调用 clzD 中的 insC 实例的 foo 方法
clzD?.insC?.foo() // func foo in ClassC
// 此时 clzD 的实例依然被 clzC 的 insD 引用,clzC 和 clzD 实例都未被释放
clzD = nil

4. Swift 弱引用 解决 循环引用 问题


// Swift5 使用 弱引用 解决 循环引用
class ClassE {
    // 弱引用 weak
    weak var insF: ClassF?
    
    deinit {
        print("deinit ClassE")
    }
    
    func foo() {
        print("func foo in ClassE")
    }
}

class ClassF {
    // 此处引用 ClassE 的实例
    var insE: ClassE?
    
    init(ins: ClassE?) {
        self.insE = ins
    }
    
    deinit {
        print("deinit ClassF")
    }
}

var clzE: ClassE? = ClassE()
var clzF: ClassF? = ClassF(ins: clzE)

clzE?.insF = clzF

// 此处 clzE 所引用的内存并未释放,对应实例被 clzF 的 insE 引用
clzE = nil
// 依然可以调用 clzF 中的 insE 实例的 foo 方法
clzF?.insE?.foo() // func foo in ClassE
// 此时 clzF 的实例被 clzE 的 insF 弱引用,会被销毁,clzE 和 clzF 实例都能被释放
clzF = nil // deinit ClassF \n deinit ClassE

5. Swift 无主引用,针对类型为非 Optional


// Swift5 无主引用,针对类型为非 Optional
class ClassG {
    // 无主引用 unowned 假定属性不为 nil
    unowned var insH: ClassH
    
    init(ins: ClassH) {
        self.insH = ins
    }
    func foo() {
        print("func foo in ClassG")
    }
    deinit {
        print("deinit ClassG")
    }
}

class ClassH {
    // 此处引用 ClassE 的实例
    var insG: ClassG?
    
    deinit {
        print("deinit ClassH")
    }

}
var clzH: ClassH? = ClassH()
var clzG: ClassG? = ClassG(ins: clzH!)


clzH?.insG = clzG

// 此处 clzG 所引用的内存并未释放,对应实例被 clzH 的 insG 引用
clzG = nil
// 依然可以调用 clzH 中的 insG 实例的 foo 方法
clzH?.insG?.foo() // func foo in ClassG
// 此时 clzH 的实例被 clzG 的 insH 无主引用,会被销毁,clzG 和 clzH 实例都能被释放
clzH = nil // deinit ClassH \n deinit ClassG

6. Swift 闭包产生的循环引用


// Swift5 闭包产生的循环引用
class ClassJ {
    var field = "field j"
    
    lazy var closure: () -> Void = {
        print(self.field)
    }
    
    deinit {
        print("deinit ClassJ")
    }
}

var objJ: ClassJ? = ClassJ()
objJ?.closure()
// 因为闭包引用了类的成员属性,导致实例无法释放,进而导致闭包无法释放,产生循环引用
objJ = nil // 此处并没有打印 deinit 中信息

7. Swift 解决闭包产生的循环引用


// Swift5 解决闭包产生的循环引用
class ClassK {
    var field = "field k"
    
    lazy var closure: () -> Void = {
        // 使用捕获列表对 self 进行无主引用的转换
        [unowned self] () -> Void in
        print(self.field)
    }
    
    deinit {
        print("deinit ClassK")
    }
}

var objK: ClassK? = ClassK()
objK?.closure()
objK = nil // deinit ClassK

8. Swift 自定义异常类型


// Swift5 自定义异常类型
enum CustomError: Error {
    case ErrorOne
    case ErrorTwo
    case ErrorThree
}

print("error")
//throw CustomError.ErrorOne // 抛出的异常未捕获会终止,不会打印 complete
print("complete")

9. Swift do-catch 捕获异常,try 执行会抛异常的函数


// Swift5 使用 do-catch 捕获异常,try 执行会抛异常的函数
// 通过函数抛出异常
func funcError() throws -> String {
    throw CustomError.ErrorTwo
}

// 使用 do-catch 捕获异常
do {
    // 使用 try 执行可能会抛出异常的函数
    try funcError()
} catch CustomError.ErrorOne {
    print("ErrorOne")
} catch CustomError.ErrorTwo {
    print("ErrorTwo")
} catch CustomError.ErrorThree {
    print("ErrorThree")
}

// 使用 try? 将函数执行的结果映射为 Optional 类型
let result = try? funcError()
if (result == nil) {
    print("exec failed")
}

// try! 强行终止异常的传递,如果发生异常,则程序中断
// try! funcError()

10. Swift 函数延时执行结构


// Swift5 函数延时执行结构:避免在抛异常的时候,保证某些必须的代码块要执行,如释放资源
func lazyFunc() throws -> Void {

    defer {
        // 函数结束时会得到执行
        print("lazy part of func")
    }
    
    print("exec lazyFunc")
    throw CustomError.ErrorThree
}

// exec lazyFunc
// lazy part of func
try? lazyFunc()

GitHub 源码:Reference&Error.playground

到此这篇关于Swift 列举内存管理与异常处理具体代码的文章就介绍到这了,更多相关Swift 内存管理与异常处理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Swift 列举内存管理与异常处理具体代码

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++技术中的内存管理:托管代码与非托管代码的内存管理差异

c++++ 中托管与非托管代码的内存管理差异:托管代码由 clr 管理,非托管代码由操作系统管理。托管代码的内存分配和释放由 clr 自动执行,非托管代码需手动管理。托管代码采用垃圾收集,非托管代码需警惕内存泄漏和段错误。托管代码内存管理简
C++技术中的内存管理:托管代码与非托管代码的内存管理差异
2024-05-08

C++技术中的内存管理:异常处理与内存泄漏的关联

在 c++++ 中,异常处理与内存泄漏密切相关,因为异常处理程序中分配的内存可能不会被释放。因此,在异常处理程序中使用智能指针或 raii 来管理内存,并使用 finally 块来确保内存释放,以防止内存泄漏。C++ 技术中的内存管理:异常
C++技术中的内存管理:异常处理与内存泄漏的关联
2024-05-07

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录