Reputation: 1939
I come across a problem when trying to exchange method:
@implementation LoginViewModel
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method fromMethod = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method toMethod = class_getClassMethod([self class], @selector(TempURLWithString:));
method_exchangeImplementations(fromMethod, toMethod);
}
});
}
+ (NSURL *)TempURLWithString:(NSString *)URLString {
NSLog(@"url: %@", URLString);
return [LoginViewModel TempURLWithString:URLString];
}
When calling [NSURL URLWithString:], I successfully get the parameter in the exchanged method TempURLWithString:. But it crashed when returning the result from the original implementation:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[LoginViewModel
URLWithString:relativeToURL:]: unrecognized selector sent to class
0x10625ff80'
What I want to do is modifying the url String when init NSURL, any one can give me some help, thanks!
Upvotes: 1
Views: 84
Reputation: 2410
The implementation of +[NSURL URLWithString:]
is basically the following:
+ (NSURL *)URLWithString:(NSString *)string {
return [self URLWithString:string relativeToURL:nil];
}
The important thing to note here is that the self
refers to the NSURL
class.
However, when you call [LoginViewModel TempURLWithString:URLString]
, the self
in the original URLWithString:
method is now a reference to the LoginViewModel
class, meaning that when the original implementation calls [self URLWithString:string relativeToURL:nil]
, that call gets dispatched to +[LoginViewModel URLWithString:relativeToURL:]
, which doesn't exist (hence the exception).
You can fix this by also adding a stub for URLWithString:relativeToURL
to your class which just forwards the call to +[NSURL URLWithString:relativeToURL:]
:
@implementation LoginViewModel
+ (NSURL *)URLWithString:(NSString *)string relativeToURL:(nullable NSURL *)relativeURL {
return [NSURL URLWithString:string relativeToURL:relativeURL];
}
@end
Upvotes: 2