Search code examples
objective-cselectorobjective-c-blocksimp

Passing in a custom selector implementation


Supposed I have two objective-c classes, LBFoo and LBBar.

In LBFoo I have a method that looks like this:

- (void)doSomethingWithFoo:(NSNumber*)anArgument
{
  if(anArgument.intValue > 2)
    [LBBar doSomethingWithLBBar];
  else
    [LBBar doSomethingElseWithLBBar];
}

What I would like to do instead is pass an implementation to LBBar that was not declared ahead of time. (As in dynamically override an existing @selector within LBBar)

I know that an IMP type exists, is it possible to pass an IMP to a class in order to change its selector implementation.


Solution

  • you can use the method_setImplementation(Method method, IMP imp) function in objective-c runtime.

    if you want to set an instance method, it would work something like this

    method_setImplementation(class_getInstanceMethod([yourClass class], @selector(yourMethod)), yourIMP);
    

    if you want a class method, just use class_getClassMethod instead of class_getInstanceMethod. The arguments should be the same.

    that's all there is to it. Note that IMP is just a void function pointer with the first 2 parameters being id self and SEL _cmd