亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

Swift中如何避免循環引用的方法

2020-03-09 17:42:57
字體:
來源:轉載
供稿:網友

內存管理中經常會遇到的一個問題便是循環引用。首先,我們來了解一下iOS是如何進行內存管理的。

和OC一樣,swift也是使用自動引用計數ARC(Auto Reference Counteting)來自動管理內存的,所以我們不需要過多考慮內存管理.當某個類實例不需要用到的時候,ARC會自動釋放其占用的內存.

ARC

ARC(Automatic Reference Counting) 是蘋果的自動內存管理機制。正如其名:自動引用計數,根據引用計數來決定內存塊是否應該被釋放。

當一個對象被創建的時候,它的引用計數為1。在它的生命周期內,其引用計數可以增加或減少。當它的引用計數減為0的時候,其所占用內存便會被釋放。其生命周期如圖所示:

Swift,避免循環引用

強引用和弱引用(Strong/Weak References)

定義一個變量的時候可以聲明其strong和weak屬性,默認是strong類型。

struct Example { var strongView = UIView() weak var weakView = UIView()}

強引用和弱引用有什么不同呢?

強引用會使變量的引用計數加1。如果一個對象的引用計數為2,當它再次被強引用的時候,它的引用計數會變為3。

弱引用不會增加引用計數。如果一個對象的引用計數為2,當它再次被弱引用的時候,它的引用計數仍為2。

強引用的對象能保證其被調用的時候仍在內存中,而弱引用不行。

循環引用和內存泄漏

當A引用B中的成員變量,而B又對A中的成員變量有引用的時候就會發生循環引用。
比如:

class Book { private var pages = [Page]()  func add(_ page : Page) {  pages.append(page) }}class Page { private var book : Book required init(book : Book) {  self.book = book }}let book = Book()let page = Page(book: book)book.add(page)

此時,book對page有強引用,同時page對book也有強引用。這個時候便有循環引用,會導致內存泄漏。

對于這種兩個變量的相互強引用導致的內存泄漏該如何解決呢?

Structs 和 Classes

正確的使用struct 和 class能避免循環引用的發生。

struct 和 class 都有成員變量,函數和協議。那么,它們之間有什么區別呢?

struct 是 值類型。
class 是 引用類型。

當引用或者傳遞 值類型 變量的時候,它會在內存中重新分配地址,copy內容到新的地址中。

struct Element { var name : String var number : Int}var firstElement = Element(name: "A", number: 1)var secondElement = firstElementsecondElement.name = "B"secondElement.number = 2print(firstElement)print(secondElement)

輸出的結果為:

Element(name: “A”, number: 1)Element(name: “B”, number: 2)

當引用或者傳遞 引用類型 變量的時候,新的變量指針指向的仍是原先的內存地址。此時原先的變量值改變的話,也會導致新變量值的變化。

比如:

class Element { var name : String var number : Int  required init(name : String, number : Int) {  self.name = name  self.number = number }}extension Element : CustomStringConvertible { var description : String {  return "Element(name: /(name), number: /(number))" }}var firstElement = Element(name: "A", number: 1)var secondElement = firstElementsecondElement.name = "B"secondElement.number = 2print(firstElement)print(secondElement)

此時的輸出結果為:

Element(name: B, number: 2)Element(name: B, number: 2)

我們為什么在此討論值類型和引用類型呢?

回到之前book和pages的例子。我們用struct代替class:

struct Book { private var pages = [Page]()  mutating func add(_ page : Page) {  pages.append(page) }}struct Page { private var book : Book  init(book : Book) {  self.book = book }}var book = Book()let page = Page(book: book)book.add(page)

此時,便不會發生循環引用的情況。

如果仍想使用class的話,可以使用weak來避免循環引用:

class Book { private var pages = [Page]()  func add(_ page : Page) {  pages.append(page) }}class Page { private weak var book : Book?  required init(book : Book) {  self.book = book }}let book = Book()let page = Page(book: book)book.add(page)

Protocols

Protocols在swift中使用的很廣泛。class,struct 和 enum 都可以使用Protocol。但是如果使用不當的話,同樣會引起循環引用。

比如:

protocol ListViewControllerDelegate { func configure(with list : [Any])}class ListViewController : UIViewController {  var delegate : ListViewControllerDelegate?  override func viewDidLoad() {  super.viewDidLoad() } }

ListViewController 中的delegate變量是strong類型的,可以引用任何實現它protocol的變量。假如實現其protocol的變量對該 view controller 同樣有強引用的話會怎么樣? 聲明delegate為weak可能會避免這種情況,但是這樣的話會引起編譯錯誤,因為structs和enums不能引用weak變量。

該如何解決呢?當聲明protocol的時候,我們可以指定只有class類型的變量可以代理它,這樣的話就可以使用weak來修飾了。

protocol ListViewControllerDelegate : class { func configure(with list : [Any])}class ListViewController : UIViewController {  weak var delegate : ListViewControllerDelegate?  override func viewDidLoad() {  super.viewDidLoad() } }

Closures

Closures 導致循環引用的原因是:Closures對使用它們的對象有一個強引用。

比如:

class Example { private var counter = 0  private var closure : (() -> ()) = { }  init() {  closure = {   self.counter += 1   print(self.counter)  } }  func foo() {  closure() } }

此時,對象對closure有一個強引用,同時在closure的代碼塊中又對該對象本身有一個強引用。這樣就引起了循環引用的發生。

這種情況,可以有兩種方法來解決這個問題。

1.使用[unowned self]:

class Example { private var counter = 1  private var closure : (() -> ()) = { }  init() {  closure = { [unowned self] in   self.counter += 1   print(self.counter)  } }  func foo() {  closure() } }

使用[unowned self] 的時候需要注意的一點是:調用closure的時候如果對象已經被釋放的話,會出現crash。

2.使用[weak self]:

class Example { private var counter = 1  private var closure : (() -> ()) = { }  init() {  closure = { [weak self] in   self?.counter += 1   print(self?.counter ?? "")  } }  func foo() {  closure() } }

[weak self] 和[unowned self] 的區別是 [weak self]處理的時候是一個可選類型。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到swift教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精自产拍久久久久久| 日本高清+成人网在线观看| 91精品国产91久久久久福利| 日韩激情第一页| …久久精品99久久香蕉国产| 日韩av三级在线观看| 亚洲国产美女精品久久久久∴| 国产精品香蕉在线观看| 亚洲国产又黄又爽女人高潮的| 欧美特级www| 欧美激情精品久久久久久蜜臀| 成人免费在线视频网站| 国产精品国产自产拍高清av水多| 亚洲成人久久久| 国产综合久久久久| 久久久久久久久综合| 色爱av美腿丝袜综合粉嫩av| 欧美日韩高清区| 国产精品亚洲一区二区三区| 黑人巨大精品欧美一区二区三区| 国外成人在线视频| 久久激情五月丁香伊人| 日本久久久久亚洲中字幕| 国产精品小说在线| 欧美黑人国产人伦爽爽爽| 国产免费久久av| 久久夜色精品亚洲噜噜国产mv| 欧美日本高清一区| 久久精品久久久久久国产 免费| 精品电影在线观看| 久久久久免费精品国产| 精品国产福利在线| 色综合色综合网色综合| 亚洲深夜福利在线| 在线看片第一页欧美| 超碰精品一区二区三区乱码| 一区二区三区国产在线观看| 亚洲国产精品国自产拍av秋霞| 国产一区二区三区精品久久久| 日韩va亚洲va欧洲va国产| 2021国产精品视频| 国产精品色婷婷视频| 欧美视频在线观看免费| 亚洲欧洲在线观看| 97**国产露脸精品国产| 91伊人影院在线播放| 亚洲网站在线播放| 欧洲s码亚洲m码精品一区| 欧美成人全部免费| 国产精品久久久一区| 成人黄色av网站| 精品日本高清在线播放| 欧美精品激情在线| 国产成人黄色av| 日韩欧美国产网站| 国产成人av网| 国产视频在线一区二区| 欧美黑人视频一区| 国产主播精品在线| 亚洲午夜小视频| 51视频国产精品一区二区| 久久99久久99精品中文字幕| 欧美性猛交xxxx乱大交极品| 国产精品久久久久久久久久新婚| 欧美国产第二页| 欧美激情精品久久久久久大尺度| 欧美夫妻性生活xx| 国产一区二中文字幕在线看| 中文字幕在线亚洲| 欧美日韩人人澡狠狠躁视频| 欧美国产高跟鞋裸体秀xxxhd| 国产精品一区二区三区久久久| 亚洲激情成人网| 欧美成人免费播放| 欧美视频第一页| 亚洲大尺度美女在线| 欧亚精品在线观看| 国产精品九九九| 日韩大片免费观看视频播放| 国产成人欧美在线观看| 国产一区二区三区毛片| 不卡av在线网站| 在线成人中文字幕| 中文字幕精品www乱入免费视频| 91亚洲精华国产精华| 亚洲一区精品电影| 伊人av综合网| 一区二区三区亚洲| 久久五月天色综合| 亚洲精品一区二区三区不| 国产精品福利无圣光在线一区| 亚洲a级在线播放观看| 欧美成人激情视频免费观看| 亚洲精品白浆高清久久久久久| 在线观看中文字幕亚洲| 亚洲va国产va天堂va久久| 日韩欧美高清在线视频| 最近2019年手机中文字幕| 国产成人免费91av在线| 亚洲天堂日韩电影| 欧美成年人视频| 欧美日韩午夜激情| 日韩中文理论片| 欧美激情小视频| 久久精品91久久香蕉加勒比| 久久免费观看视频| 中文字幕亚洲第一| 国产精品久久久久国产a级| 久久久久一本一区二区青青蜜月| 久久人体大胆视频| 岛国视频午夜一区免费在线观看| 插插插亚洲综合网| 九九热这里只有在线精品视| 亚洲欧洲偷拍精品| 欧美裸体视频网站| 精品国产91久久久久久| 国产人妖伪娘一区91| 欧美成人国产va精品日本一级| 久久国产一区二区三区| 亚洲欧洲日产国产网站| 午夜精品久久久久久99热软件| 亚洲欧洲日产国产网站| 亚洲天堂影视av| 韩国精品美女www爽爽爽视频| 精品人伦一区二区三区蜜桃网站| 亚洲一区二区自拍| 久久久精品久久久| 亚洲激情自拍图| 国产一区二区成人| 91亚洲精品一区| 91精品视频免费观看| 国产精品久久久久久搜索| 欧美激情一区二区三级高清视频| 欧美大全免费观看电视剧大泉洋| 久久精品国产一区二区三区| 亚洲成人性视频| 欧美精品第一页在线播放| 中文字幕亚洲一区| 亚洲激情中文字幕| 国产精品美女无圣光视频| 亚洲精品wwww| www.日本久久久久com.| 在线精品播放av| 国语自产偷拍精品视频偷| 国产精品免费电影| 黄网站色欧美视频| 国产日韩在线播放| 最近中文字幕mv在线一区二区三区四区| 91精品国产高清自在线| 九九热在线精品视频| 亚洲欧美精品中文字幕在线| 欧美在线视频a| 91亚洲精品一区| 日韩精品免费视频| 国产精品久久国产精品99gif| 欧美肥老太性生活视频| 日韩成人中文字幕在线观看| 国产精品海角社区在线观看| 91免费观看网站| 日韩亚洲成人av在线| 91精品国产色综合久久不卡98| 91精品国产91久久久久久吃药| 韩国国内大量揄拍精品视频| 91精品国产乱码久久久久久蜜臀|