Created by Jamz Tang at 17 February 2013
There are many reasons for you to use method swizzling, even if it's considered harmful and dangerous.
Despite it's flaws, this little technique can be so powerful and let you reveal secrets of iOS like status bar is drawn by the current app, and replace methods in class you don't own like customizing UINavigationBar background in old days to achieve a higher level of UI customisation.
So here's the base snippet:
/*
* This file is part of the http://ioscodesnippet.com
* http://ioscodesnippet.com/2013/02/17/method-swizzling-in-objective-c/
* (c) Jamz Tang <jamz@jamztang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
void SwizzleInstanceMethod(Class c, SEL orig, SEL new);
void SwizzleClassMethod(Class c, SEL orig, SEL new);
/*
* This file is part of the http://ioscodesnippet.com
* http://ioscodesnippet.com/2013/02/17/method-swizzling-in-objective-c/
* (c) Jamz Tang <jamz@jamztang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <objc/runtime.h>
void SwizzleInstanceMethod(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);
}
void SwizzleClassMethod(Class c, SEL orig, SEL new) {
Method origMethod = class_getClassMethod(c, orig);
Method newMethod = class_getClassMethod(c, new);
c = object_getClass((id)c);
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);
}
Example usage:
@implementation NSParagraphStyle (JTParagraphStyleDebug)
+ (void)load {
SwizzleInstanceMethod([self class], @selector(initWithCoder:), @selector(initWithCoderSwizzled:));
}
// -[NSParagraphStyle initWithCoder:] is called when an NSAttributedString is specified in an UILabel in Interface Builder.
- (id)initWithCoderSwizzled:(NSCoder *)aDecoder {
self = [self initWithCoderSwizzled:(id)[[UINibDecoderProxy alloc] initWithTarget:aDecoder]];
return self;
}
@end
Above code is extracted from JTAttributedLabel to use UINibDecoderProxy to diagnose NSAttributedString in Interface Builder.
Enjoy and have a good use with it!
Using CocoaPods: [?]
pod 'MethodSwizzle', '~> 0.0.1'
Clone this repository:
git clone git://gist.github.com/4970366.git MethodSwizzle
If you think this is useful, share this article with your friends :)
blog comments powered by DisqusUINibDecoderProxy Observes what's encoded in an NSCoder object
JTKeyValueObserver Revisiting KVO+Block, the simplest version.
MethodSwizzle Method Swizzling in Objective-C
UITableViewDeleteActionResponder Quick hack to enable delete menu item in UITableView menuController
UIApplicationAddition Quickly switch supported UIInterfaceOrientation for your View Controllers
JTTargetActionBlock Adding Block support for UIControl's Target-Action mechanism
NSArray-JTArraySplit Splitting an array to several components
UIImage+JTImageDecode Force decompressing UIImage in background to achieve better performance
UINavigationBar-JTDropShadow Adding drop shadow on UINavigationBar (before iOS 6)
UIImage-JTImageCrop Crop an image in specific rect
UIView+JTRemoveAnimated Adding fadeout effect to any -[UIViews removeFromSuperview]
JTStringAddition NSStringf. Simpler printf styled +[NSString stringWithFormat:]
UIView-JTViewToImage Rendering any UIViews into UIImage in one line (updated with iOS 7 support)
NSObject-JTNibLoader Loading a Nib file programmatically using NSObject category
UIImage-JTColor Creating a placeholder UIImage dynamically with color
NSObject-JTCancelableScheduledBlock Cancelable Scheduled Blocks in Objective-C