Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change an object's superclass

Is it possible to change an object's superclass at runtime? If so, how?

like image 763
AndrewShmig Avatar asked Feb 25 '13 05:02

AndrewShmig


2 Answers

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.

like image 132
vikingosegundo Avatar answered Sep 21 '22 15:09

vikingosegundo


It is definitely possible using ObjC runtime, but it will be a bit hairy... This is a link to Apple's docs: Objective-C Runtime and an example of its usage: Objective-C Runtime Programming.

like image 38
Vineet Singh Avatar answered Sep 18 '22 15:09

Vineet Singh