如何覆盖框架类中的方法(运行时)

时间:2012-09-27 03:30:27

标签: objective-c ios runtime

问题
框架将在上面缓存图像数据:

[UIImage imageNamed:]

我不希望缓存发生,所以我可以用

替换它
[UIImage imageOfContentOfFile:]

似乎已经解决,但在我的测试之后,在xib的实例化进度中,框架使用 imageNamed:而不是 imageOfContentOfFile
也就是说,xib加载的图像仍然被缓存。

所以我尝试覆盖UIImage的imageNamed:方法,使所有这些方法都不要高速缓存。

- try1。类别:

@implementation UIImage (ImageNamedNoCache)

+ (UIImage *)imageNamed:(NSString *)name; 
{
    NSString* path = [[NSBundle mainBundle] pathForResource:name ofType:nil];
    return [UIImage imageWithContentsOfFile:path];
}

@end

- 结果:警告。“类别正在实施一种方法,该方法也将由其主要类”

实施

- try2。运行时替换方法的imp

    //get super method
Method method_imageNamed = class_getClassMethod([UIImage class], @selector(imageNamed:));

//get my method
Method method_myImageNamed = class_getClassMethod([self class], @selector(myImageNamed:));

//get my imp
IMP imp_myImageNamed = method_getImplementation(method_myImageNamed);

//set super method's imp to my imp
method_setImplementation(method_imageNamed, imp_myImageNamed);

- 结果 这些也只在我调用 [UIImage imageNamed:]时才有效 但是xib的实例化不起作用。

帮助我,谢谢

4 个答案:

答案 0 :(得分:1)

听起来像method swizzling的工作。我发现它很危险且没必要,但如果你这么倾向,它一个选项。使用风险自负。

答案 1 :(得分:0)

类别方法应该没问题,只需给你的方法一个不同的名字。我的理解是,覆盖一个类别中的方法并不是一个好习惯,但添加一个新方法就没问题了。

答案 2 :(得分:0)

如果我没有正确解释,请纠正我,但看起来你的核心问题是你在加载xib时试图让框架(即Apple代码)调用imageWithContentsOfFile而不是imageNamed。

第三个选项可能是将UIImageViews作为占位符留在xib“blank”中,然后以编程方式将UIImages稍后加载到它们中(例如在FileOwner的init代码中),也许借助于'tag'属性+字典,以确定正确的图像,如果方便的话。或者你甚至可以动态地创建图像和它们的视图,而不是将它们保存在xib文件中。显然这里有很多权衡。

答案 3 :(得分:0)

  1. 你的解决方案并不好:)使用缓存是有充分理由的。
  2. 只是不要在你的代码中使用[UIImage imageNamed:],一切都会好的
  3. 如果实际不需要缓存图片,则应使用方法#2。
  4. 注意:来自XIBS的图片(实际上是所有对象)都加载了-[object initWithCoder:],而不加载[UIImage imageNamed:][UIImage imageWithContentsOfFile:]