How to override a method in framework's class (runtime)

百般思念 提交于 2019-12-09 13:40:00

问题


problem:
framework will cache the image data when above:

[UIImage imageNamed:]

I don't want the caching happen,so I can replace it by

[UIImage imageOfContentOfFile:]

Seems solved,but after my tests,in xib's instantiate progress, framework uses imageNamed: rather than imageOfContentOfFile.
That is, images loaded by xib still cached.

So I try to override the UIImage's imageNamed: method, make all this method DO NOT CACHE.

--try1. category:

@implementation UIImage (ImageNamedNoCache)

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

@end

--result:warning."Category is implementing a method which will also be implemented by its primary class"

--try2. runtime replace the method's 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);

--result these too try only work when I invoke [UIImage imageNamed:]
but xib's instantiation doesn't work.

help me, thanks


回答1:


Sounds like a job for method swizzling. I find it dangerous and unnecessary, but if you are so inclined, it is an option. Use at your own risk.




回答2:


The category method should be fine, just give your method a different name. It's my understanding that it's not good practice to override methods in a category, but adding a new one is fine.




回答3:


Correct me if I do not interpret correctly, but it looks like your core problem is that you are trying to get framework (i.e., Apple code) to call imageWithContentsOfFile instead of imageNamed when loading xibs.

A third option might be to leave the UIImageViews in the xib 'blank' as a placeholder, and then programmatically loading UIImages into them later (for example in the FileOwner's init code), perhaps with the help of the 'tag' property + a dictionary to determine the right image, if it's convenient. Or you could even create both the images and their views dynamically instead of keeping them in the xib file. Obviously there are lots of tradeoffs here.




回答4:


  1. Your solution isn't good :) Caching is used for good reasons.
  2. Just don't use [UIImage imageNamed:] In YOUR code, and all will be fine
  3. If you Actually need not to cache your images, you should use method #2.

NOTE: Images(actually, all objects) from XIBS are being loaded with -[object initWithCoder:], and not with [UIImage imageNamed:] or [UIImage imageWithContentsOfFile:]



来源:https://stackoverflow.com/questions/12613673/how-to-override-a-method-in-frameworks-class-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!