swift 列举内存管理与异常处理具体代码-kb88凯时官网登录

来自:网络
时间:2023-07-25
阅读:
免费资源网 - https://freexyz.cn/

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 源码:

免费资源网 - https://freexyz.cn/
返回顶部
顶部
网站地图