关于iOS中图片加载的两种方式的区别以及和内存的关系

参考链接:http://blog.csdn.net/ys410900345/article/details/26503279

在修改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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值