如何在纯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+ 浏览量

启动你的职业生涯

通过完成课程获得认证

开始学习
广告