国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Swift - Swift中轉義閉包示例詳解

Swift中轉義閉包示例詳解

2021-12-26 17:37小小小_小朋友 Swift

在Swift 中的閉包類似于結構塊,并可以在任何地方調用,下面這篇文章主要給大家介紹了關于Swift中轉義閉包的相關資料,需要的朋友可以參考下

前言

Swift 是一種非常強大的編程語言,是為 Apple 生態系統開發應用程序的首選;iOS、macOS、watchOS 和 tvOS。作為使用 Swift 編寫代碼的開發人員,我們經常使用閉包;語言的一個重要而重要的章節。

閉包不是初學者開始的主題。然而,這是每個人都必須盡快了解的東西。有很多方面需要了解并了解它們的工作原理。在所有這些中,有一個特定的;轉義閉包和@escaping屬性。在這篇文章中,我將盡可能簡單地解釋它們是什么以及它們可能帶來的附帶影響。

 

轉義與非轉義閉包

在談論轉義閉包時,我們總是指作為函數或方法參數提供的閉包。一般來說,我們將提供給方法(或函數)的閉包分為兩類:

  1. 在方法執行完成之前調用的閉包。
  2. 在方法執行完成后調用的閉包。

在后一種情況下,我們談論的是轉義閉包;關閉該繼續即使電子住后的的xecution方法,直到我們在以后的任何時間在未來給他們打電話。

在前一種情況下,與我上面描述的完全相反,我們稱閉包為non-escaping。

直到 Swift 3,默認情況下,所有作為參數傳遞給方法或函數的閉包都被認為是轉義的。自 Swift 3 以來,這不再正確;默認情況下,所有方法都被認為是非轉義的,這意味著它們在方法執行完成之前被調用。

以下代碼部分演示了一個非轉義閉包:

func  add(num1:  Double,

num2:  Double,

completion:  (_  result:  Double)  ->  Void)  {

let  sum  =  num1  +  num2

completion(sum)

}

所述completion封閉件之前執行代碼葉調用的方法,所以這不是一個逸出閉合的情況。

然而,一個閉包是如何從一個方法中逃脫的,所以我們最終得到了與上述情況相反的結果?

 

逃離方法

為了使閉包成為轉義閉包,有必要將對其的引用保留在方法的范圍之外,以便我們稍后使用它。看看下面的代碼:

class  Demo  {
var  result:  Double?
var  resultHandler:  (()  ->  Void)?
func  add2(num1:  Double,
num2:  Double,
completion:  ()  ->  Void)  {
resultHandler  =  completion
result  =  num1  +  num2
}
}

這里我們有一個result屬性,它保存在方法內部發生的加法的結果。但我們也resultHandler有財產;this 保持對completion作為方法參數提供的閉包的引用。

閉包通過以下行從方法中轉義:

resultHandler  =  completion

然而,這不是唯一需要的操作,所以我們可以說這completion是一個轉義閉包。我們必須明確指出編譯器,否則我們將在 Xcode 中看到以下錯誤:

Swift中轉義閉包示例詳解

為了修復它,我們需要用@escaping屬性標記閉包。我們將此屬性放在閉包名稱和分號之后,但在閉包類型之前,如下所示:

func  add2(num1:  Double,
num2:  Double,
completion:  @escaping  ()  ->  Void)  {
...
}

編譯器不再抱怨,completion現在正式成為轉義閉包。

 

將轉義關閉付諸行動

讓我們在上面的Demo類中再添加兩個方法;一個將調用add2(num1:num2:completion:)方法,另一個將調用resultHandler閉包以獲得最終結果:

class  Demo  {
...
func  doubleSum(num1:  Double,
num2:  Double)  {
add2(num1:  num1,  num2:  num2)  {
guard let  result  =  self.result  else  {  return  }
self.result  =  result  *  2
}
}

func  getResult()  {
resultHandler?()
}
}

第一種方法將 add 方法計算的結果加倍。但是,該結果不會翻倍,并且在add2(num1:num2:completion:)我們調用該getResult()方法之前,不會執行該方法中閉包主體內的代碼。

這是我們從轉義閉包中受益的地方;我們可以在我們的代碼中需要的時候以及在合適的時機觸發閉包的調用。盡管提供的示例故意過于簡單,但在實際項目中,實際優勢會變得更加明顯和大膽。

 

注意強參考周期

讓我們為Demo類添加最后一個,并實現默認的初始化器和析構器方法:

class  Demo  {
init()  {
print("Init")
}
deinit  {
print("Deinit")
}
...
}

init()是Demo初始化實例時調用的第一個方法,deinit也是釋放實例之前調用的最后一個方法。我向它們都添加了一個打印命令,以驗證它們是否被調用,并且在使用帶有上述轉義閉包的方法時沒有內存泄漏。

注意:當我們嘗試通過將對象設置為 nil 來釋放它時,可能存在內存泄漏,但該對象仍保留在內存中,因為該對象與其他保持其活動狀態的對象之間存在強引用。

現在,讓我們添加以下幾行來使用上述所有內容:

var  demo:  Demo?  =  Demo()
demo?.doubleSum(num1:  5,  num2:  10)
demo?.getResult()
print((demo?.result!)!)
demo  =  nil

首先,我們初始化類的一個可選實例Demo,以便稍后我們可以將其設為 nil。然后,我們調用該doubleSum(num1:num2:)方法以將作為參數給出的兩個數字相加,然后將該結果加倍。但是,正如我之前所說的,在我們調用該getResult()方法之前不會發生這種情況;在方法中實際調用轉義閉包的那個add2(num1:num2:completion:)。

最后,我們打印實例中result屬性的值demo,并將其demo設為 nil。

*注意:*如上面的代碼片段所示,使用感嘆號 (!) 強制展開可選值是一種非常糟糕的做法,請不要這樣做。我在這里這樣做的唯一原因是為了讓事情盡可能簡單。

以上行將打印以下內容:

Init

30.0

請注意,此處缺少“Deinit”消息!也就是說deinit沒有調用該方法,證明制作demo實例nil沒有實際結果。看起來,只需幾行簡單的代碼,我們就設法解決了內存泄漏問題。

 

內存泄漏背后的原因

在我們找到解決內存泄漏的方法之前,有必要了解它發生的原因。為了找到它,讓我們退后幾步來修改我們之前所做的。

首先,我們使用以下completion行使閉包從方法中逃逸:

resultHandler  =  completion

這條線比看起來更“有罪”,因為它創建了對閉包的強烈引用completion。

注意:閉包是引用類型,就像類一樣。

然而,僅憑這一點還不足以產生問題,因為釋放demo實例會刪除對閉包的引用。真正的麻煩始于doubleSum(num1:num2:)方法內部的閉包主體。

在那里,我們這次通過在使用對象訪問屬性時捕獲**對象來創建另一個從閉包到demo實例的強引用:selfresult

guard let  result  =  self.result  else  {  return  }
self.result  =  result  *  2

當它們都到位時,Demo 實例保持對閉包的強引用,而閉包則是對實例的強引用。這會創建一個保留循環,也稱為強引用循環。發生這種情況時,每個引用類型都會使另一個引用類型在內存中保持活動狀態,因此它們最終都不會被釋放。

請注意,這僅發生在包含帶有轉義閉包的方法的類中。structs 的情況有所不同,因為它們不是引用而是值類型,并且顯式引用self不是強制性的。

 

消除強引用循環

有兩種方法可以避免強引用循環,從而避免內存泄漏。第一個是在我們調用閉包后手動且顯式地釋放對閉包的引用:

func  getResult()  {
resultHandler?()
// Setting nil to resultHandler removes the reference to closure.
resultHandler  =  nil
}

第二種方法是在閉包的主體中弱**捕獲self實例:

func  doubleSum(num1:  Double,
num2:  Double)  {
add2(num1:  num1,  num2:  num2)  {  [weak  self]  in
guard let  result  =  self?.result  else  {  return  }
self?.result  =  result  *  2
}
}

[weak self] in在關閉打開后查看添加。有了這個,我們建立了對 Demo 實例的弱引用,因此我們避免了保留循環。請注意,我們將self用作可選值,并在其后加上問號 (?) 符號。

沒有必要應用這兩種更改以避免強引用循環。無論我們最終選擇哪一個,從現在開始,輸出也將包含“Deinit”消息。這意味著該demo對象變為 nil,并且我們不再有內存泄漏。

Init

30.0

Deinit

 

概括

離開這里需要帶上一件事,那就是在使用轉義閉包時要小心。無論您是實現自己的接受轉義閉包作為參數的方法,還是使用具有轉義閉包的 API,請始終確保不會以強引用循環結束。在開發應用程序時,內存泄漏是一個很大的“禁忌”,我們當然不希望我們的應用程序在某個時候崩潰或因此被系統終止。另一方面,不要猶豫使用轉義閉包;它們提供了可以產生更強大代碼的優勢。

到此這篇關于Swift中轉義閉包的文章就介紹到這了,更多相關Swift轉義閉包內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/7025872329431334920

延伸 · 閱讀

精彩推薦
  • SwiftSwift教程之基礎數據類型詳解

    Swift教程之基礎數據類型詳解

    這篇文章主要介紹了Swift教程之基礎數據類型詳解,本文詳細講解了Swift中的基本數據類型和基本語法,例如常量和變量、注釋、分號、整數、數值類型轉換等...

    Swift教程網5162020-12-18
  • SwiftSwift的74個常用內置函數介紹

    Swift的74個常用內置函數介紹

    這篇文章主要介紹了Swift的74個常用內置函數介紹,這篇文章列舉出了所有的Swift庫函數,內置函數是指無需引入任何模塊即可以直接使用的函數,需要的朋友可...

    Swift教程網5802020-12-19
  • SwiftSwift中轉義閉包示例詳解

    Swift中轉義閉包示例詳解

    在Swift 中的閉包類似于結構塊,并可以在任何地方調用,下面這篇文章主要給大家介紹了關于Swift中轉義閉包的相關資料,需要的朋友可以參考下...

    小小小_小朋友11412021-12-26
  • SwiftSwift能代替Objective-C嗎?

    Swift能代替Objective-C嗎?

    這是我在網上上看到的答案,復制粘貼過來和大家分享一下,因為我和很多人一樣很關心Swift的出現對Mac開發的影響和對Objective-C的影響。...

    Swift教程網4412020-12-16
  • Swiftswift where與匹配模式的實例詳解

    swift where與匹配模式的實例詳解

    這篇文章主要介紹了swift where與匹配模式的實例詳解的相關資料,這里附有簡單的示例代碼,講的比較清楚,需要的朋友可以參考下...

    追到夢的魔術師14382021-01-06
  • SwiftSwift實現多個TableView側滑與切換效果

    Swift實現多個TableView側滑與切換效果

    這篇文章主要為大家詳細介紹了Swift實現多個TableView側滑與切換效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    乞力馬扎羅的雪雪5822021-01-08
  • SwiftSwift使用CollectionView實現廣告欄滑動效果

    Swift使用CollectionView實現廣告欄滑動效果

    這篇文章主要為大家詳細介紹了Swift使用CollectionView實現廣告欄滑動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Stevin的技術博客12372021-01-13
  • Swiftmac git xcrun error active developer path 錯誤

    mac git xcrun error active developer path 錯誤

    本文主要是講訴了如何解決在mac下使用git;xcode4.6的環境時,出現了錯誤(mac git xcrun error active developer path)的解決辦法,希望對大家有所幫助...

    Swift教程網2232020-12-16
主站蜘蛛池模板: 999精品一区 | 日韩精品一区二区三区在线观看 | 国产精品久久久久久久久久 | 粉色在线观看 | 黄毛片免费看 | 婷婷久久综合九色综合绿巨人 | 日韩在线视频中文字幕 | 一 级 黄 色 片免费网站 | 免费岛国视频 | 亚洲成人综合网站 | 欧美激情在线观看 | 久草在线免费福利资源 | 欧美a一级 | 亚洲 欧美 日韩 在线 | 亚洲精品在线观看网站 | 精品久久久久久久久久久久久久 | 久久国产综合 | 在线观看午夜 | 成人午夜性成交 | 91国在线产 | 丝袜+亚洲+另类+欧美+变态 | 激情久久免费视频 | 亚洲一区二区免费视频 | www久| 日韩一区电影 | 国产成人精品免费 | 国内自拍视频在线观看 | 中文日韩在线 | 99久久婷婷国产综合精品电影 | 国产这里只有精品 | 九九色综合 | 欧美一级精品片在线看 | 免费的av| 一区二区三区四区免费看 | 欧美在线一区二区 | 成年人黄色免费网站 | 亚洲一区在线播放 | 久久久久久国产精品 | 国产乱码一区二区三区在线观看 | 色中色综合 | 自拍 亚洲 欧美 老师 丝袜 |