Skip to content

Instantly share code, notes, and snippets.

@Air-Craft
Last active August 29, 2015 14:06
Show Gist options
  • Save Air-Craft/517f88c5865d923a02b6 to your computer and use it in GitHub Desktop.
Save Air-Craft/517f88c5865d923a02b6 to your computer and use it in GitHub Desktop.
Objective-C Category method swizzling and injection #runtime #advanced #objective-c #swizzle
// FOR CATEGORIES (From same class into same class)
// `swizzle()` allows replacing methods in a Category while still leaving access
// to the original akin to `super` for subclasses
// INJECT/REPLACE (loses original)
void (^inject)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
Method newMethod = class_getInstanceMethod(c, new);
class_replaceMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
};
// SWIZZLE (old method is available under new one's name)
void (^swizzle)(Class, SEL, SEL) = ^(Class c, SEL orig, SEL new){
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
};
// USAGE
// Note, call [self _my_prepareForSegue:sender] for original version
swizzle(self.class, @selector(prepareForSegue:sender:), @selector(_my_prepareForSegue:sender:));
// Pure override/replace
inject(self.class, @selector(delegate), @selector(_es_delegate));
inject(self.class, @selector(setDelegate:), @selector(_es_setDelegate:));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment