最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

swift中defer的實際應(yīng)用小結(jié)

 更新時間:2021年01月04日 15:44:43   作者:Harious  
這篇文章主要給大家介紹了關(guān)于swift中defer的實際應(yīng)用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

看看蘋果官方的介紹

用 defer 語句在即將離開當(dāng)前代碼塊時執(zhí)行一系列語句。該語句讓你能執(zhí)行一些必要的清理工作,不管是以何種方式離開當(dāng)前代碼塊的——無論是由于拋出錯誤而離開,或是由于諸如 return、break 的語句。例如,你可以用 defer 語句來確保文件描述符得以關(guān)閉,以及手動分配的內(nèi)存得以釋放。
defer 語句將代碼的執(zhí)行延遲到當(dāng)前的作用域退出之前。該語句由 defer 關(guān)鍵字和要被延遲執(zhí)行的語句組成。延遲執(zhí)行的語句不能包含任何控制轉(zhuǎn)移語句,例如 break、return 語句,或是拋出一個錯誤。延遲執(zhí)行的操作會按照它們聲明的順序從后往前執(zhí)行——也就是說,第一條 defer 語句中的代碼最后才執(zhí)行,第二條 defer 語句中的代碼倒數(shù)第二個執(zhí)行,以此類推。最后一條語句會第一個執(zhí)行。

總結(jié)一下蘋果官方的介紹

defer語句在代碼塊(方法、閉包等,可以理解為大括號包裝起來的代碼)作用域退出之前\color{red}{作用域退出之前}作用域退出之前執(zhí)行,也就是代碼塊中其他應(yīng)該執(zhí)行的代碼都執(zhí)行完了,才執(zhí)行defer中的代碼
一個代碼塊允許多個defer,多個defer執(zhí)行的順序從后到前\color{red}{從后到前}從后到前

一些測試及誤區(qū)糾正

測試案例1

func testDefer() {
 defer {
 print("方法中defer內(nèi)容")
 }
 if true {
 defer {
  print("if 中defer內(nèi)容")
 }
 print("if中最后的代碼")
 }
 print("方法中的代碼")
 if true {
 return
 }
 print("方法結(jié)束前最后一句代碼")
}
testDefer()

以上代碼打印結(jié)果:

if中最后的代碼
if 中defer內(nèi)容
方法中的代碼
方法中defer內(nèi)容

打印結(jié)果中,第一個if中的代碼及里面的defer最先執(zhí)行,方法中的defer最后執(zhí)行,由此可以看出,代碼塊中其他能夠執(zhí)行的代碼先執(zhí)行,最后執(zhí)行defer的內(nèi)容;defer的作用范圍不能簡單的看成方法,而是代碼塊(可能有些同學(xué)會有這樣的誤區(qū))

測試案例2

func testDefer() {
 print("開始")
 defer {
 print("defer 1 中的內(nèi)容")
 }
 defer {
 print("defer 2 中的內(nèi)容")
 }
 if true {
 return
 }
 defer {
 print("defer 3 中的內(nèi)容")
 }
 print("方法結(jié)束前最后一句代碼")
}
testDefer()

打印結(jié)果

開始
defer 2 中的內(nèi)容
defer 1 中的內(nèi)容

我們可以看到最后一個defer沒有執(zhí)行,所以defer定義的位置很重要,如果沒有執(zhí)行defer定義的代碼,在代碼塊結(jié)束前不會執(zhí)行defer中的內(nèi)容

多個defer的執(zhí)行順序從后到前

一些實際應(yīng)用場景

場景1:一些資源用完后需釋放,這里給的是官方的一個案例

func processFile(filename: String) throws {
 if exists(filename) {
 let file = open(filename)
 defer {
  close(file)
 }
 while let line = try file.readline() {
  // 處理文件。
 }
 // close(file) 會在這里被調(diào)用,即作用域的最后。
 }
}

開始用到資源的時候就使用defer去釋放,避免忘記釋放資源

場景2:加鎖解鎖,借鑒了kingfisher

let lock = NSLock()
func testDefer() {
 lock.lock()
 defer {
 lock.unlock()
 }
 
 doSomething()
}
testDefer()

在加鎖后立刻用defer解鎖,避免忘記解鎖

場景3:處理一些代碼塊作用域結(jié)束前的重復(fù)操作,比如請求網(wǎng)絡(luò)數(shù)據(jù)的時候

通常的一種寫法

func loadCityList(_ finish: ((Error?, [String]?) -> ())?) {
 DispatchQueue.global().async { // 模擬網(wǎng)絡(luò)請求
 let data: AnyObject? // 模擬服務(wù)器返回的數(shù)據(jù)
 guard let dict = data as? [String: AnyObject] else {
  DispatchQueue.main.async {
  finish?(error, nil)
  }
  return
 }
 guard let code = dict["code"] as? Int, code == 200 else {
  DispatchQueue.main.async {
  finish?(error, nil)
  }
  return
 }
 guard let citys = dict["data"] as? [String]? else {
  DispatchQueue.main.async {
  finish?(error, nil)
  }
  return
 }
 DispatchQueue.main.async {
  finish?(nil, citys)
 }
 }
}

當(dāng)每次有錯誤處理時和結(jié)果正確時都需要去做回調(diào),而且回調(diào)可能有一堆代碼,看起來代碼會比較冗余,而且在一些錯誤處理時很容易造成忘記回調(diào)

defer怎么去寫呢

func loadCityList(_ finish: ((Error?, [String]?) -> ())?) {
 DispatchQueue.global().async { // 模擬網(wǎng)絡(luò)請求
 var error: Error? = nil
 var citys: [String]? = nil
 defer {
  DispatchQueue.main.async {
  finish?(error, citys)
  }
 }
 
 let data: AnyObject? // 模擬服務(wù)器返回的數(shù)據(jù)
 guard let dict = data as? [String: AnyObject] else {
  error = ...
  return
 }
 guard let code = dict["code"] as? Int, code == 200 else {
  error = ...
  return
 }
 guard let tempCitys = dict["data"] as? [String]? else {
  error = ...
  return
 }
 citys = tempCitys
 }
}

使用defer既解決了代碼冗余,又解決了可能忘記回調(diào)的問題,還有當(dāng)我們看到defer時,我們很清楚知道,無論網(wǎng)絡(luò)請求結(jié)果如果,都會回調(diào)

總結(jié)

本文主要介紹了defer的定義、作用及一些用法

到此這篇關(guān)于swift中defer的實際應(yīng)用的文章就介紹到這了,更多相關(guān)swift中defer應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SwiftUI學(xué)習(xí)之state和Binding的區(qū)別淺析

    SwiftUI學(xué)習(xí)之state和Binding的區(qū)別淺析

    這篇文章主要給大家介紹了關(guān)于SwiftUI學(xué)習(xí)之state和Binding區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • swift4 使用DrawerController實現(xiàn)側(cè)滑菜單功能的示例代碼

    swift4 使用DrawerController實現(xiàn)側(cè)滑菜單功能的示例代碼

    這篇文章主要介紹了swift4 使用DrawerController實現(xiàn)側(cè)滑功能的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 在 Swift 中測試 UIAlertController的方法

    在 Swift 中測試 UIAlertController的方法

    這篇文章主要介紹了在 Swift 中測試 UIAlertController的方法的,需要的朋友可以參考下
    2015-10-10
  • Swift語言中的函數(shù)學(xué)習(xí)教程

    Swift語言中的函數(shù)學(xué)習(xí)教程

    這篇文章主要介紹了Swift語言中的函數(shù)學(xué)習(xí)教程,著重講了Swift函數(shù)的參數(shù)傳遞用法,需要的朋友可以參考下
    2015-11-11
  • 詳解Swift的內(nèi)存管理

    詳解Swift的內(nèi)存管理

    這篇文章主要介紹了Swift的內(nèi)存管理,對內(nèi)存管理感興趣的同學(xué),可以參考下
    2021-04-04
  • Swift如何為設(shè)置中心添加常用功能

    Swift如何為設(shè)置中心添加常用功能

    這篇文章主要給大家介紹了關(guān)于Swift如何為設(shè)置中心添加常用功能的相關(guān)資料,包含了跳轉(zhuǎn)到AppStore、郵件反饋功能、系統(tǒng)分享功能以及打開某些網(wǎng)址等功能,需要的朋友可以參考借鑒,下面來一起看看吧
    2018-05-05
  • 解析Swift語言面相對象編程中的繼承特性

    解析Swift語言面相對象編程中的繼承特性

    這篇文章主要介紹了解析Swift語言面相對象編程中的繼承特性,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • swift中c風(fēng)格的for循環(huán)執(zhí)行效率

    swift中c風(fēng)格的for循環(huán)執(zhí)行效率

    這篇文章主要介紹了swift中c風(fēng)格的for循環(huán)執(zhí)行效率 的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • 探討Swift數(shù)組和字典

    探討Swift數(shù)組和字典

    Swift數(shù)組是具體的。他不同于Objective-C的的NSArray和NSMutableArray里的類,它可以存儲任何類型的對象,不提供有關(guān)它們返回的對象的性質(zhì)的任何信息
    2015-12-12
  • Swift編程中數(shù)組的使用方法指南

    Swift編程中數(shù)組的使用方法指南

    這篇文章主要介紹了Swift編程中數(shù)組的使用方法指南,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11

最新評論

交城县| 邵东县| 柏乡县| 高密市| 镇巴县| 平山县| 盈江县| 安平县| 建湖县| 都兰县| 乐都县| 武川县| 九江市| 忻城县| 伊金霍洛旗| 偏关县| 新营市| 榕江县| 临邑县| 禹城市| 神池县| 西贡区| 崇阳县| 清流县| 综艺| 克山县| 万荣县| 荣昌县| 精河县| 平顺县| 乌鲁木齐县| 江油市| 山东| 合川市| 桃源县| 伽师县| 岐山县| 莱西市| 灵山县| 永康市| 波密县|