Method Swizzling in Swift

Pallavi Dipke
5 min readJan 14, 2022

--

If you know about method dispatch then method swizzling is not new for you. Even after being big fan of OOP, I didn’t know much about Method Swizzling before. I did digging into for few days and came up with clear picture of Method Swizzling. So let’s explore this topic today without wasting time.

Method Dispatch

What are use cases of method swizzling?

Let’s say you got a task to to keep track of all the screens user is visiting. Its very simple right? Simply create a subclass of UIViewController that will hold a function which will perform the tracking logic and we will call that function in viewWillAppear(_ animated: Bool) then only thing is left is, use that UIViewController class as a base class for all the controllers. But this is not proper solution as, It has following issues.

  1. You have one UITableViewController class and that also need to be logged but when I tried to use our base class as a super class of UITableViewController it showed following error. The reason behind this error is UITableViewController is child of UIViewController. Swift doesn’t allow to perform multiple inheritance.

2. You might be using other frameworks and libraries which may have UIViewControllers, also UITableViewControllers which need to be logged. Now the question here is how you will inherit those UIViewControllers and UITableViewControllers?

3. Same point 2 in reverse order. If you are a framework developer and you have to track the screens. You can not ask your users to sub class all the screens with your controller so that tracking of screens will be performed.

  • Here, You may write to the library author to use your class as base class so that you can fulfil your requirement with this approach.
  • Else, You would have studied about method swizzling and completed the task.

If you ask me I would have given the task to other teammate and relaxed 😁😁. Joke a part, I would have gone with Method swizzling.

What is method swizzling?

Method swizzling is the process of changing the implementation of an existing selector at runtime. Simply speaking, we can change the functionality of a method at runtime.This is possible with the power of objective C runtime.

Now first question pop up in my mind that what exactly happens at the memory level when method swizzling (Message Dispatch) happens. Here what happens -

  • In case of message dispatch compiler does not have any direct dispatch mechanism nor witness table to look into to execute the function. Actually compiler crawl to the hierarchy of classes to determine which method to invoke. This is comparatively very slow compared to direct and table dispatch but still there are some use cases where is no option out there.

How to achieve it?

Following code will creates an extension of UIViewController. Let’s understand the code now.

  • swizzle() function holds a logic for swizzling. Here it will get the references of the methods which we want to exchange at runtime.
  • create a function which we want to execute at runtime when the message dispatches for particular method. In example. We have created _tracked_viewWillAppear(_ animated: Bool). Here we can write the logic of tracking the screens which is our problem statement.
  • class_getInstanceMethod(_ cls: AnyClass?, _ name: Selector) -> Method? This objective C function which will return the pointers for the function. It takes two parameters, one is type of AnyClass, We will set self here and method selector is second parameter which will be #selector.
  • Here we have to get pointers of two methods and store it in a local variable. In example we have to get pointers of _tracked_viewWillAppear(_:) and viewDidLoad.
  • Then the last step for this function is exchange the implementation by using method_exchangeImplementations(_ m1: Method, _ m2: Method) function.
  • To execute this throughout the app just call the method from AppDelegate. Tired 😟?? Relax now, you are all done with the coding for the given problem statement.
Swizzling Method implementation.
Calling Swizzling function for all ViewControllers.
  • You might wonder we are calling _tracked_viewWillAppear(animated) inside _tracked_viewWillAppear(_:). This may call the same function infinite times and it will never come out of loop. But it’s not like that. In fact it will call the viewDidLoad() with _tracked_viewWillAppear(_:) call.

Here is output of this code:-

Outcome of the code.

Things to be careful for

  • Method swizzling is very dynamic in nature as takes decision at runtime, hence we have to be very careful while using it as it has ability to mess up the app if you are not using it properly.
  • Trouble shooting can be very difficult if something goes wrong.
  • The order of swizzle matters, so be careful when swizzling multiples classes. For example if you swizzle UIView and UIButton you must be careful because UIButton inherits from UIView through UIControls.
  • You have to keep track of iOS releases and have to check that your code is running properly with the updates. Even Firebase does swizzling for few methods but it allows us to disable the it.
  • Uses subclassing wherever possible until its necessary to go with swizzling.

This is all for now on this topic, Hope it improved your understanding about Method swizzling.

Articles that inspired me to learn about swizzling.

If you find this article useful , give a clap so that medium recommends it to others.

Swift iOS Method Dispatch iOS Development Method Swizzling Monkey Patching

--

--