Created
September 14, 2011 21:43
-
-
Save mschulkind/1217885 to your computer and use it in GitHub Desktop.
ObjC Swizzlin'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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