Skip to content

Instantly share code, notes, and snippets.

@kylef
Last active January 2, 2016 02:19
Show Gist options
  • Save kylef/8236477 to your computer and use it in GitHub Desktop.
Save kylef/8236477 to your computer and use it in GitHub Desktop.
Replace a method on an instance at runtime
+ (void)load {
/* We want to add our method after the application has finished launching
because that's when the key window should be setup.
We will add a method to that instance. */
/*
WARNING
This would fail if another object was to key value observe the object
we are going change the class of before we change it. That means before
UIApplicationDidFinishLaunchingNotification is fired.
*/
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidFinishLaunchingNotification object:[UIApplication sharedApplication] queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
UIApplication *application = [note object];
UIWindow *window = [application keyWindow];
Class windowClass = object_getClass(window);
Method originalMotionMethod = class_getInstanceMethod(windowClass, @selector(motionEnded:withEvent:));
const char *methodEncoding = method_getTypeEncoding(originalMotionMethod);
IMP motionImplementation = imp_implementationWithBlock(^(UIWindow *window, UIEventSubtype motion, UIEvent *event) {
struct objc_super superInfo = {
window,
windowClass
};
objc_msgSendSuper(&superInfo, @selector(motionEnded:withEvent:), motion, event);
NSLog(@"It works, implementation should go here.");
});
Class mfWindowClass = objc_allocateClassPair(windowClass, "MFWindow", 0);
class_addMethod(mfWindowClass, @selector(motionEnded:withEvent:), motionImplementation, methodEncoding);
objc_registerClassPair(mfWindowClass);
object_setClass(window, mfWindowClass);
[[NSNotificationCenter defaultCenter] removeObserver:note];
}];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment