日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Swift解决【闭包引起的循环强引用】

發布時間:2025/3/17 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Swift解决【闭包引起的循环强引用】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

循環強引用還會發生在當你將一個閉包賦值給類實例的某個屬性,并且這個閉包體中又使用了這個類實例時。這個閉包體中可能訪問了實例的某個屬性,例如self.someProperty,或者閉包中調用了實例的某個方法,例如self.someMethod()。這兩種情況都導致了閉包“捕獲”self,從而產生了循環強引用。

解決閉包引起的循環強引用

在定義閉包時同時定義捕獲列表作為閉包的一部分,通過這種方式可以解決閉包和類實例之間的循環強引用。捕獲列表定義了閉包體內捕獲一個或者多個引用類型的規則。跟解決兩個類實例間的循環強引用一樣,聲明每個捕獲的引用為弱引用或無主引用,而不是強引用。應當根據代碼關系來決定使用弱引用還是無主引用。

注意 Swift 有如下要求:只要在閉包內使用self的成員,就要用self.someProperty或者self.someMethod()(而不只是someProperty或someMethod())。這提醒你可能會一不小心就捕獲了self。

定義捕獲列表

捕獲列表中的每一項都由一對元素組成,一個元素是weak或unowned關鍵字,另一個元素是類實例的引用(例如self)或初始化過的變量(如delegate = self.delegate!)。這些項在方括號中用逗號分開。

如果閉包有參數列表和返回類型,把捕獲列表放在它們前面:

lazy var someClosure: (Int, String) -> String = {[unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in// 這里是閉包的函數體 } 復制代碼

如果閉包沒有指明參數列表或者返回類型,即它們會通過上下文推斷,那么可以把捕獲列表和關鍵字in放在閉包最開始的地方:

lazy var someClosure: Void -> String = {[unowned self, weak delegate = self.delegate!] in// 這里是閉包的函數體 } 復制代碼
弱引用和無主引用

在閉包和捕獲的實例總是互相引用并且總是同時銷毀時,將閉包內的捕獲定義為無主引用。

相反的,在被捕獲的引用可能會變為nil時,將閉包內的捕獲定義為弱引用。弱引用總是可選類型,并且當引用的實例被銷毀后,弱引用的值會自動置為nil。這使我們可以在閉包體內檢查它們是否存在。

注意 如果被捕獲的引用絕對不會變為nil,應該用無主引用,而不是弱引用。

案例

class HTMLElement {let name: Stringlet text: String?lazy var asHTML: Void -> String = {[unowned self] inif let text = self.text {return "<\(self.name)>\(text)</\(self.name)>"} else {return "<\(self.name) />"}}init(name: String, text: String? = nil) {self.name = nameself.text = text}deinit {print("\(name) is being deinitialized")}} 復制代碼

捕獲列表是[unowned self],表示“將self捕獲為無主引用而不是強引用”。

創建并打印HTMLElement實例:

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world") print(paragraph!.asHTML()) // 打印 “<p>hello, world</p>” 復制代碼

使用捕獲列表后引用關系如下圖所示:

這一次,閉包以無主引用的形式捕獲self,并不會持有HTMLElement實例的強引用。如果將paragraph賦值為nil,HTMLElement實例將會被銷毀,并能看到它的析構函數打印出的消息:

paragraph = nil // 打印 “p is being deinitialized” 復制代碼

引自:http://www.piggybear.net/?p=690

轉載于:https://juejin.im/post/5a312c936fb9a0450f21f062

總結

以上是生活随笔為你收集整理的Swift解决【闭包引起的循环强引用】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。