由于某些原因,我必须保留原始代码而不做任何修改,但是尝试将系统API重定向到我的代码中,然后回调到原始代码。例如,我想在[NSString stringWithFormat:]
中做更多的事情。是否有可能在Objective-C中重定向系统API?
现在我尝试使用方法swizzling。但似乎NSString
未在主运行时加载,我将调整方法移动到MyAppDelegate
。之后class_getInstanceMethod([NSString class], @selector(stringWithFormat:)
)不是零。但是,调整方法仍然不起作用,因为class_getInstanceMethod([NSString class], @selector(override_stringWithFormat:))
仍然是零,我该如何解决这个问题?
感谢, CLU
@interface NSString (MyNSString)
+ (id)stringWithFormat:(NSString *)format, ...;
@end
@implementation NSString (MyNSString)
+ (id)stringWithFormat:(NSString *)format, ... {
//do something...
[NSString stringWithFormat:format];
}
@end
这里是MyAppDelegate
#import "MyNSString.h"
-(void) MethodSwizzle:(Class)c replaceOrig:(SEL) origSEL withNew:(SEL) overrideSEL {
Method origMethod = class_getInstanceMethod(c, origSEL);
Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
if(class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod)))
class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, overrideMethod);
}
- (BOOL) application:(UIApplication*) application didFinishLaunchingWithOptions:(NSDictionary *) options {
...
//Unit test
NSString *a=[NSString override_stringWithFormat:@"Test"]; //returned something
Method b = class_getInstanceMethod([NSString class], @selector(override_stringWithFormat:)); //return nil;
//do something...
[self MethodSwizzle:[NSString class] replaceOrig:@selector(stringWithFormat:) withNew:@selector(override_stringWithFormat:)];
}
RyanR,谢谢你的信息。我知道类别,但它创建了一种新方法,重写我的代码以使用新类型是很可怕的,因为我在任何地方都使用NSString。所以我想只导入我的新MyNSString,它会替换现有的NSString方法。如果我想使用原始的,它更加灵活。在C++中,我可以使用#typedef将调用(如printf)重定向到我拥有的,但我不知道如何在objective-c中执行此操作。 – clu
嗨RyanR,我已经更新了我的问题,但仍然陷入混乱的方法,你有什么建议吗?再次感谢。 – clu
你可能很难重写你的代码来使用一个新的类,但是看看你现在正在经历多少麻烦,去做一些可能给你带来更大问题的事情。 – sosborn