a short question, a short answer: yes, isa swizzling
What Makes Objective C Dynamic?, page 66
An example:
I have a class that handles connections to a REST-API, it is called APIClient. In testing I want to connect to a different server.
In the testing target I subclass APIClient
#import "ApiClient.h"
@interface TestApiClient : ApiClient
//…
@end
@interface TestApiClient ()
@property (nonatomic, strong, readwrite) NSURL *baseURL;
@end
@implementation TestApiClient
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
path:(NSString *)path
parameters:(NSDictionary *)parameters
{
self.baseURL = [NSURL URLWithString:@"http://localhost:8000/"];
return [super requestWithMethod:method path:path parameters:parameters];
}
@end
In the Unit test class I do the swizzling
#import
@implementation APIUnitTests
+(void)load
{
client = [[ApiClient alloc ] init];
object_setClass(client, [TestApiClient class]);
}
//…
@end
This cas is save, as I first created a subclass of an base class and then replaced the latter with the subclass. As the subclass is also a base class, this is valid inheritance.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…