Skip to content

Instantly share code, notes, and snippets.

@mschulkind
Created September 14, 2011 21:43
Show Gist options
  • Save mschulkind/1217885 to your computer and use it in GitHub Desktop.
Save mschulkind/1217885 to your computer and use it in GitHub Desktop.
ObjC Swizzlin'
// Every class using this inherits from the class defining these methods,
// and provides a +uiKitSubclass method which returns the class object of
// the class which should be swizzled.
+ (void)subclassMethod:(SEL)selector
withImplementation:(IMP)subclassedImplementation
{
Method uiKitMethod = class_getInstanceMethod([self uiKitSubclass], selector);
assert(uiKitMethod);
BOOL methodAdded =
class_addMethod(
[self uiKitSubclass], selector, subclassedImplementation,
method_getTypeEncoding(uiKitMethod));
// If the method wasn't added (because it already exists), we replace the
// method and save the original implementation for later.
if (!methodAdded) {
Method method = class_getInstanceMethod([self uiKitSubclass], selector);
IMP originalImplementation =
method_setImplementation(method, subclassedImplementation);
objc_setAssociatedObject(
[self uiKitSubclass], (void*)subclassedImplementation,
[NSValue valueWithPointer:(void*)originalImplementation],
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
+ (IMP)getOriginalImplementation:(IMP)subclassedImplementation
forSelector:(SEL)selector
andSelf:(id)aSelf
{
// First check for a saved implementation.
NSValue* originalImplementation =
objc_getAssociatedObject(
[aSelf class], (void*)subclassedImplementation);
if (originalImplementation) {
return (IMP)[originalImplementation pointerValue];
} else {
// Otherwise return super's implementation if it exists.
Class superclass = class_getSuperclass([aSelf class]);
Method superMethod = class_getInstanceMethod(superclass, selector);
if (superMethod) {
return method_getImplementation(superMethod);
} else {
return NULL;
}
}
}
// Then to call the original implementation inside the new implementation:
IMP originalDealloc =
[UIComponentPlugin getOriginalImplementation:(IMP)dealloc
forSelector:_cmd
andSelf:self];
originalDealloc(self, _cmd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment