当你用一个类别来重写系统的方法时候
比如:
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {
return [self aCustomFontOfSize:fontSize];}
xcode会提示你 "Category is implementing a method which will also be implemented by its primary class".
去除这种警告的几种方法
1.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
// do your override
#pragma clang diagnostic pop
better alternative (see bneely's answer to why this warning is saving you from disaster) is to use method swizzling. By using method swizzling, you can replace an existing method from a category without the uncertainty of who "wins", and while preserving the ability to call through to the old method. The secret is to give the override a different method name, then swap them using runtime functions.
#import
#import
void MethodSwizzle(Class c, SEL orig, SEL new) {
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
}
Then define your custom implementation:
+ (UIFont *)mySystemFontOfSize:(CGFloat)fontSize {
...
}
MethodSwizzle([UIFont class], @selector(systemFontOfSize:), @selector(mySystemFontOfSize:));
Try this in your code:
+(void)load{
EXCHANGE_METHOD(Method1, Method1Impl);
}
#import
#define EXCHANGE_METHOD(a,b) [[self class]exchangeMethod:@selector(a) withNewMethod:@selector(b)]
@interface NSObject (MethodExchange)
+(void)exchangeMethod:(SEL)origSel withNewMethod:(SEL)newSel;
@end
#import
@implementation NSObject (MethodExchange)
+(void)exchangeMethod:(SEL)origSel withNewMethod:(SEL)newSel{
Class class = [self class];
Method origMethod = class_getInstanceMethod(class, origSel);
if (!origMethod){
origMethod = class_getClassMethod(class, origSel);
}
if (!origMethod)
@throw [NSException exceptionWithName:@"Original method not found" reason:nil userInfo:nil];
Method newMethod = class_getInstanceMethod(class, newSel);
if (!newMethod){
newMethod = class_getClassMethod(class, newSel);
}
if (!newMethod)
@throw [NSException exceptionWithName:@"New method not found" reason:nil userInfo:nil];
if (origMethod==newMethod)
@throw [NSException exceptionWithName:@"Methods are the same" reason:nil userInfo:nil];
method_exchangeImplementations(origMethod, newMethod);
}
@end