更多技术文章请关注我的微博: http://weibo.com/u/2822867275 ------------------------------------------在修改xcode比较大的项目时,通常会遇到一种很蛋疼的情况: 项目中很多地方调用一个方法,但是这个方法的功能不太理想,于是你想修改这个方法,最后发现这个方法来源于一个Lib, 没有代码,只有 定义在 .h 文件,泥马没有代码怎么修改阿?小牛哥在做 Westfield Leasing 这个项目时也遇到类似的操蛋经历,这个app用到很多tmd大图片,一般正常人都用 [UIImage imageNamed: ] 这个方法,但是在调试中发现,泥马这个方法会不断占用cash的内存,导致程序很快就阳痿(内存不够)! 而 [UIImage imageWithContentsOfFile:] 就不会。这样我们单独写一个方法好了, 像[UIImage xpImageNamed:] 这样的category! 里面调用imageWithContentsOfFile: 就好了?听起来可行,但两个问题:1. 在一个大项目里,人员流动也频繁,有新人进来你得不断的告诉他/她:别用imageNamed:啦,会阳痿的 要是新人是个小清纯,你好意思不?
2. 项目里原来可能就有几百个地方用imageNamed:, 如果用一个新的函数代替,将会有几百个地方要修改,这个不是高效率的方法。 而且当你commit 代码时,别的程序员看到这么多地方被修改,得拿出看AV的认真态度,多累阿
**
所以最好的方法是在整个项目中替换掉imageNamed:这个方法, 当其他人用这个方法时,系统其实会调用另一个方法!
请看下面代码!以下方法称为 Method Swizzling, 当你引用下面的头文件时,在整个项目中[UIImage imageNamed: ]  这个方法会被 [UIImage myImageNamed:] 这个方法替换掉。 
PS:
在iOS7中, 如果你的 UIBarButtonItem 是以 initWithCumstomView: 建立的,会出现移位的情况,这时可以用 Method Swizzling 来解决,详情请关注小牛的的下一篇文章。
#import <UIKit/UIKit.h>@interface UIImage (Common)
+(UIImage*)myImageNamed: (NSString*)imageName;
@end
#import "UIImage+Common.h"
#import <objc/runtime.h>
#import <objc/message.h>
@implementation UIImage (Common)// load 在初始化类时调用,每个类都有一个load 方法,
// 类的初始化先于对象
+(void)load
{
    //以下方法就告诉系统用后面的方法替换前面的
    method_exchangeImplementations(class_getClassMethod(self, @selector(imageNamed:)),
                                   class_getClassMethod(self, @selector(myImageNamed:)));
}+(UIImage*)myImageNamed: (NSString*)imageName
{
    // 图片要支持jpg 和png 
    NSString *path = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
    
    if (path == nil)
    {
        path = [[NSBundle mainBundle] pathForResource:imageName ofType:@"jpg"];
    }
    
    // 这里image 在回收后不会占用cash 内存
    UIImage *image = [UIImage imageWithContentsOfFile:path];
    
    return image;
}@end