È possibile modificare la superclasse di un oggetto in fase di runtime? Se é cosi, come?Modifica dinamica della superclasse di un oggetto
risposta
una breve domanda, una risposta breve: sì, isa swizzling
What Makes Objective C Dynamic?, page 66
Un esempio:
ho una classe che gestisce le connessioni a un REST API, è chiamato APIClient. Nei test voglio connettermi a un server diverso.
Nel target test ho sottoclasse 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
nella classe di test Unità faccio la swizzling #import
@implementation APIUnitTests
+(void)load
{
client = [[ApiClient alloc ] init];
object_setClass(client, [TestApiClient class]);
}
//…
@end
Questo CAS è salva, come ho prima creato una sottoclasse di un classe base e quindi sostituito quest'ultimo con la sottoclasse. Poiché la sottoclasse è anche una classe base, questa è un'ereditarietà valida.
Questo sembra estremamente pericoloso. Perché mai vorresti? –
se fatto bene è molto potente, Apple lo usa per KVO: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOImplementation.html – vikingosegundo
Io personalmente lo uso per ispezionare codice: sottoclassi e sovrascrivo i metodi a cui sono interessato per registrare alcune informazioni e chiamare i metodi originali su super. – vikingosegundo
È sicuramente possibile utilizzare il runtime ObjC, ma sarà un po 'peloso ... Questo è un collegamento ai documenti di Apple: Objective-C Runtime e un esempio del suo utilizzo: Objective-C Runtime Programming.
Dai un'occhiata a http://stackoverflow.com/questions/11221110/my-isa-swizzling-breaks-kvo per un esempio di isa swizzle. – mttrb
Inoltre, che cosa significa "la superclasse di un oggetto"? Un * oggetto * non ha una superclasse. Un oggetto ha una classe e la sua classe ha una superclasse. Se invece tu modifichi la superclasse della classe dell'oggetto, ** tutti i membri di quella classe saranno interessati, ** non solo quel singolo oggetto. –
perché la superclasse non è una classe corrente? cosa succede alla classe attuale? prima devi pensare attentamente –