Skip to content

Instantly share code, notes, and snippets.

@kylef kylef/instance-swizzle.m
Last active Jan 2, 2016

Embed
What would you like to do?
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
You can’t perform that action at this time.