What is a de-initializer and how is it written in Swift?


In this article, you will learn how and why to use a de-initializer in the Swift language. You will learn the concept of de-initializing using some examples.

When a class instance is no longer required, Swift automatically calls a specific method called a deinitializer. It is utilized to carry out any necessary cleanup prior to deallocating an item from memory. The "deinit" keyword is used to create a deinitializer, which has no parameters or output.

Syntax 

Here is the basic syntax of a de-initializer in Swift

class ClassName {
   // Other properties and methods
    
   deinit {
      // Perform cleanup tasks
   }
}

You can use the deinit block to perform cleanup tasks like releasing the resources(like closing the file, releasing the memory), canceling the scheduled tasks, freeing the memory, etc.

As soon as a class instance is about to be deallocated from memory, a de-initializer is invoked. This indicates that it is used to carry out any cleanup procedures that must be carried out before the item is erased from memory. This may involve doing things like freeing memory that was allocated while the item was in use. It might also entail canceling any connected tasks that are planned or closing any open files.

The de-initializer only functions with classes; structs are not supported. This is due to the fact that structs cannot be deallocated. They are value types instead, and when the variable corresponding to them leaves their scope, the memory is deallocated.

Example 

Here's an example of a class that uses a deinitializer to cancel a scheduled task

import Foundation
class MyTimer {
   var timer: Timer?
    
   init() {
      timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
   }    
   deinit {
      timer?.invalidate()
   }    
   @objc func timerFired() {
      // do something
   }
}

In the above example, When MyTImer class is initialized, it creates a timer. This timer is automatically canceled when the class instance is no longer required. The de-initializer calls the invalidate method of the timer to cancel the scheduled task.

It's crucial to keep in mind that de-initializers are only called when a class instance is no longer required. This has the practical effect of reducing the instance's reference count to 0.

Example 

Here's another example of a class that uses a deinitializer to release memory that was allocated during its lifetime

import Foundation
class MyData {
   var data: UnsafeMutableRawPointer?
   var size: Int
    
   init(size: Int) {
      self.size = size
      data = UnsafeMutableRawPointer.allocate(byteCount: size, alignment: 1)
   }
    
   deinit {
      data?.deallocate()
   }
}

In this example, after initialization, the class MyData allocates memory by calling the allocation function of UnsafeMutableRawPointer. When a class instance is no longer required, memory is automatically deallocated. To release memory, the deinitializer executes the data pointer's deallocate procedure.

Example 

Here's another useful example of a class that uses a deinitializer to release a resource that was acquired using a singleton pattern

import Foundation
class MySingleton {
   static let shared = MySingleton()
   var resource: Resource?
    
   private init() {
      resource = acquireResource()
   }    
   deinit {
      releaseResource(resource: resource)
   }
}

In the above example, it is using acquireResource function to acquire a resource right after the MySingleton class is initialized. the resource will get automatically removed as soon as the class instance usage is complete. To perform this operation deinitializer calls the releaseResource function by taking resource as the parameter.

Note − The class MySignleton uses a singleton pattern and its instance is shared by the entire application. Due to this, the deinitializer will not be called as the class instance won't get deallocated.

Here are a few advantages of using deinitializers in Swift 

  • Resource management − Before an object is removed from memory, you can execute any necessary cleanup operations using de-initializers. This can include actions like freeing up memory, putting an end to open files, and stopping scheduled operations.

  • Memory management − When a class instance is no longer required, deinitializers are an excellent approach to make sure that resources are released in the correct manner. By doing so, memory leaks—which can result in an application using more memory than necessary—can be avoided.

  • Error handling − You don't have to worry about calling deinitializers manually because they are called automatically. This entails that cleanup operations can be carried out by de-initializers even in the presence of errors, which can help to prevent an application from crashing.

  • Proper cleanup − Make that the resource is deallocated when the object is deallocated when you create an object that contains a reference to another resource. Deinitializers aid you in accomplishing this in a dependable and regular manner.

  • Consistent resource usage − A good technique to guarantee that resources are obtained and released uniformly across all instances of a class is to use deinitializers. By doing so, errors may be avoided and it may be simpler to understand how an application behaves.

  • Good practice − Deinitializing is recommended because it guarantees that resources are released correctly and is a best practice for memory management. By doing this, you can ensure that your code doesn't leave any open files or free RAM behind.

Conclusion

In Swift, you can use de-initializers to free up memory usage in the code. You can ensure that resources are properly deallocated when they are no longer required. It helps to manage memory leaks and other errors that might occur in the application and present the possibility of crashes.

Updated on: 28-Feb-2023

127 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements