Playing around dynamic metod replacement on per-instance basis (think Decorator using runtime)
//
// Copyright © 2013 Advantis
//
#import "NSObject+ADVDynamicMethodOverride.h"
#import <objc/runtime.h>
static const char *SubclassPrefix = "ADVOverriding";
@implementation NSObject (ADVDynamicMethodOverride)
- (BOOL) replaceMethod:(SEL)selector withBlock:(id)block
{
Class class = object_getClass(self);
const char *className = class_getName(class);
if (className != strstr(className, SubclassPrefix))
{
// Create dynamic subclass
char *subclassName;
asprintf(&subclassName, "%s_%s", SubclassPrefix, className);
Class subclass = objc_getClass(subclassName) ?: objc_allocateClassPair(class, subclassName, 0);
free(subclassName);
if (Nil == subclass) return NO;
// OPTIONAL: Hide the existence of this dynamic subclass
IMP classImp = imp_implementationWithBlock(^(__unused id this){
return class;
});
class_addMethod(subclass, @selector(class), classImp, "@@:");
objc_registerClassPair(subclass);
object_setClass(self, subclass);
class = object_getClass(self);
}
Method method = class_getInstanceMethod(class, selector);
if (NULL == method) return NO;
IMP imp = imp_implementationWithBlock(block);
const char *types = method_getTypeEncoding(method);
return class_addMethod(class, selector, imp, types);
}
@end
//
// Copyright © 2013 Advantis
//
#import <Foundation/Foundation.h>
// typedef id(^ADVMethodImp)(id super, ...);
@interface NSObject (ADVDynamicMethodOverride)
- (BOOL) replaceMethod:(SEL)selector withBlock:(id)block;
@end