1. Swift 內存銷毀時機
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/ / 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 單向引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/ / 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 循環引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
/ / 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 弱引用 解決 循環引用 問題
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/ / 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
/ / 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 閉包產生的循環引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/ / 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 解決閉包產生的循環引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/ / 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 自定義異常類型
1
2
3
4
5
6
7
8
9
10
|
/ / Swift5 自定義異常類型 enum CustomError: Error { case ErrorOne case ErrorTwo case ErrorThree } print ( "error" ) / / throw CustomError.ErrorOne / / 拋出的異常未捕獲會終止,不會打印 complete print ( "complete" ) |
9. Swift do-catch 捕獲異常,try 執行會拋異常的函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/ / 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 函數延時執行結構
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/ / 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 內存管理與異常處理內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/java_android_man/article/details/121503916