如何在純Swift中(不使用@objc)建立弱協議引用?


在Swift中,你可以使用`weak`關鍵字宣告持有協議引用的變數或屬性來建立弱協議引用。弱引用有助於避免建立迴圈引用。

什麼是弱協議引用?

Swift中的弱協議引用是一種定義協議的技術,類可以使用該協議而不會啟動強引用迴圈。當兩個物件相互保持強引用,阻止任何一個物件被釋放時,這被稱為強引用迴圈。透過持有對它的弱協議引用,一個物件能夠在不再需要時釋放另一個物件。

為什麼弱引用應該是一個變數?

弱引用會隨著時間的推移而變化並變為nil,因此弱變數應宣告為變數而不是常量(用`let`宣告)。你可以使用弱引用來避免對專案的強引用。如果程式的其餘部分不再需要它,這將有助於釋放物件。

一旦完成,所有強引用都將被移除,但弱引用不會。相反,弱引用將設定為nil以指示它們以前引用的物件不再位於記憶體中。如果弱引用是一個常量,它將無法在它引用的物件被釋放時更改為nil,這可能會導致程式出現意外行為。

語法如下:

weak var delegate: MyProtocol?

因此,委託變數將成為一個對符合MyProtocol協議的物件的弱引用。因為在Swift中,協議引用預設是可選的。

請記住,只有在必要時才應使用對變數或屬性的弱引用。這是必要的,因為如果它不是可選的並且變為nil,你的程式碼將會崩潰。

示例

當然,這是一個名為VehicleDrivingProtocol的協議示例:

protocol VehicleDrivingProtocol: class {
   func drive()
}
class Vehicle: VehicleDrivingProtocol { 
   var make: String
   var model: String
   var year: Int
   var numDoors: Int
   var isConvertible: Bool
   
   init(make: String, model: String, year: Int, numDoors: Int, isConvertible: Bool) {
      self.make = make
      self.model = model
      self.year = year
      self.numDoors = numDoors
      self.isConvertible = isConvertible
   }    
   func drive() {
      print("The \(make) \(model) is driving.")
   }
}
class Car {   
   weak var delegate: VehicleDrivingProtocol?
   func callDelegate() {
      delegate?.drive()
   }
}

// Here is an example of how you can set the delegate in the Car class:
let vehicleObject = Vehicle(make: "Tata", model: "Nano", year: 2016, numDoors: 4, isConvertible: true)
let carObject = Car()
carObject.delegate = vehicleObject
carObject.callDelegate()

輸出

The Tata Nano is driving.

在此示例中,Car類的delegate屬性是對符合VehicleDrivingProtocol協議的物件的弱引用。`callDelegate()`方法僅當delegate不為nil時才在delegate上呼叫`drive()`方法。如果Car是唯一對委託物件的強引用,則委託是弱的。如果你沒有對它的強引用,ARC將釋放委託物件。

結論

你可以使用`weak var`在Swift中建立對符合協議的物件的弱引用。弱引用意味著你不想對物件保持強引用。這是因為如果程式碼的其餘部分不再需要該物件,則可以釋放該物件。

弱引用應該宣告為變數而不是常量,因為它們會隨著時間的推移而發生變化並變得無效。為了防止它變為nil時崩潰,它也應該是可選的。這對於防止記憶體洩漏並確保你的程式有效利用記憶體至關重要。

更新於:2023年2月28日

1K+ 瀏覽量

啟動你的職業生涯

透過完成課程獲得認證

開始學習
廣告
© . All rights reserved.