Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swizzling a single instance, not a class

I have a category on NSObject which supposed to so some stuff. When I call it on an object, I would like to override its dealloc method to do some cleanups.

I wanted to do it using method swizzling, but could not figure out how. The only examples I've found are on how to replace the method implementation for the entire class (in my case, it would override dealloc for ALL NSObjects - which I don't want to).

I want to override the dealloc method of specific instances of NSObject.

@interface NSObject(MyCategory)
-(void)test;
@end

@implementation NSObject(MyCategory)
-(void)newDealloc
{
  // do some cleanup here
  [self dealloc]; // call actual dealloc method
}
-(void)test
{
  IMP orig=[self methodForSelector:@selector(dealloc)];
  IMP repl=[self methodForSelector:@selector(newDealloc)];
  if (...)   // 'test' might be called several times, this replacement should happen only on the first call
  {
     method_exchangeImplementations(..., ...);
  }
}
@end
like image 798
Gilad Novik Avatar asked Feb 29 '12 18:02

Gilad Novik


People also ask

What is swizzling method?

Method swizzling is the process of replacing the implementation of a function at runtime. Swift, as a static, strongly typed language, did not previously have any built-in mechanism that would allow to dynamically change the implementation of a function.

What is swizzling in Swift?

iOS Swift Tips. Swizzling (other languages call this “monkey patching”) is the process of replacing a certain functionality or adding custom code before the original code is called. For example, you could swizzle UIViewController.


1 Answers

You can't really do this since objects don't have their own method tables. Only classes have method tables and if you change those it will affect every object of that class. There is a straightforward way around this though: Changing the class of your object at runtime to a dynamically created subclass. This technique, also called isa-swizzling, is used by Apple to implement automatic KVO.

This is a powerful method and it has its uses. But for your case there is an easier method using associated objects. Basically you use objc_setAssociatedObject to associate another object to your first object which does the cleanup in its dealloc. You can find more details in this blog post on Cocoa is my Girlfriend.

like image 116
Sven Avatar answered Sep 29 '22 23:09

Sven