我正在尝试用自己的实现替换UIImage的类方法。
在某些情况下,我的实现可能只想调用原始的UIImage实现。
这是我的代码
#import "UIImage+SkinnedImage.h"
#import <objc/runtime.h>
@interface UIImage (SkinnedImagePrivate)
+ (UIImage *)originalImageNamed:(NSString*)name;
@end
@implementation UIImage (SkinnedImage)
+ (void)allowSkinning {
Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
IMP originalImageNamedIMP = class_getMethodImplementation_stret([UIImage class], @selector(imageNamed:));
Method swizzled = class_getClassMethod([UIImage class], @selector(skinnedImageNamed:));
method_exchangeImplementations(imageNamedMethod, swizzled);
const char *signatureEnconding = method_getTypeEncoding(imageNamedMethod);
class_addMethod([UIImage class], @selector(originalImageNamed:), originalImageNamedIMP, signatureEnconding);
}
+ (UIImage *)skinnedImageNamed:(NSString *)name {
//XXX
return [UIImage originalImageNamed:name];
}
@end
+ (void)allowSkinning
被召唤。+ (UIImage *)skinnedImageNamed:(NSString *)name
被调用而不是+ (UIImage *)imageNamed:(NSString *)name;
return [UIImage originalImageNamed:name];
因错误而崩溃:原因:'+ [UIImage originalImageNamed:]:无法识别的选择器发送到 类
为什么要class_addMethod([UIImage类],@ selector(originalImageNamed :),originalImageNamedIMP,signatureEnconding);未能为我提供实施?
请注意,函数class_addMethod返回true
答案 0 :(得分:3)
此行将实例方法-originalImageNamed:
添加到UIImage
:
class_addMethod([UIImage class], @selector(originalImageNamed:), originalImageNamedIMP, signatureEnconding);
您可以将其更改为:
class_addMethod(object_getClass([UIImage class]), @selector(originalImageNamed:), originalImageNamedIMP, signatureEnconding);
或等同地:
class_addMethod(objc_getMetaClass("UIImage"), @selector(originalImageNamed:), originalImageNamedIMP, signatureEnconding);
类方法是类的元类的实例方法。因此,向该元类添加实例方法会向类添加类方法。
您拨打class_getMethodImplementation_stret()
的问题也存在类似问题。该函数获取实例方法的实现。因此,如果你想获得一个类方法,你必须通过该类的元类:
IMP originalImageNamedIMP = class_getMethodImplementation(object_getClass([UIImage class]), @selector(imageNamed:));
或者,既然您已经拥有相应的Method
,那么您可以这样做:
IMP originalImageNamedIMP = method_getImplementation(imageNamedMethod);
顺便问一下,你为什么要使用class_getMethodImplementation_stret()
? +imageNamed:
不会返回结构。