Created by Jamz Tang at 17 February 2013

Method Swizzling in Objective-C

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 <[email protected]>
 *
 * 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 <[email protected]>
 *
 * 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 to diagnose NSAttributedString in Interface Builder.

Enjoy and have a good use with it!


Installation

Using CocoaPods: [ ? ]
pod 'MethodSwizzle', '~> 0.0.1'

Clone this repository:
git clone git://gist.github.com/4970366.git MethodSwizzle

| More...


If you think this is useful, share this article with your friends :)

blog comments powered by Disqus

ioscodesnippet.com