How can I make a weak protocol reference in 'pure' Swift (without @objc)?


In Swift, you can make a weak protocol reference by using the weak keyword when declaring the variable or property that holds the reference to the protocol. The weak reference helps you to avoid the retain cycle creation.

What is a weak protocol reference?

A weak protocol reference in Swift is a technique for defining a protocol that a class can use without starting a strong reference cycle. When two objects maintain strong references to one another, preventing either object from being deallocated, this is known as a strong reference cycle. One of the objects is able to deallocate the other when it is no longer required by holding a weak protocol reference to it.

Why a weak reference should be a variable?

Weak references can change and become nil over time, hence a weak variable should be stated as a variable rather than a constant (declared with a let). You can avoid holding a strong reference to an item by using a weak reference. It will help in de-allocating the object if the remainder of the program no longer requires it.

once that is done, all of its strong references will be removed, but weak references won't. Instead, weak references are set to nil to indicate that the object they previously referred to is no longer in memory. If a weak reference were a constant, it would not be able to change to nil when the object it refers to is deallocated, and this could lead to unexpected behavior in the program.

The syntax would be

weak var delegate: MyProtocol?

The delegate variable will then become a weak reference to an object that conforms with the MyProtocol protocol as a result. Because protocol references are by default optional in Swift.

Keep in mind that a weak reference to a variable or property should only be used if necessary. This is necessary since your code will crash if it is not optional and turns into nil.

Example 

Sure, here is an example of a protocol called 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()

Output

The Tata Nano is driving.

The delegate property of the Car class in this example is a weak reference to an object that conforms with the VehicleDrivingProtocol protocol. Only if the delegate is not nil does the callDelegate() method invoke the drive() method on the delegate. If Car is the only strong reference to the delegate object, the delegate is weak. ARC will deallocate the delegate object if you don't have a strong reference to it.

Conclusion

You can create a weak reference to an object that conforms with a protocol in Swift by using weak var. You don't want to keep a strong reference to an object, which is what a weak reference means. This is because the object can be deallocated if the rest of the code no longer needs it.

Weak references should be variables rather than constants since they can change and become obsolete over time. In order to prevent crashing if it becomes nil, it should also be optional. This is essential to protect against memory leaks and to make sure that your program makes effective use of memory.

Updated on: 28-Feb-2023

816 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements