Come creare un protocollo in fase di runtime in Objective-C?
-
26-09-2019 - |
Domanda
Innanzitutto voglio che sia chiaro che non sto parlando di definire un protocollo, e che ne intendo il concetto
@protocol someprotocol
- (void)method;
@end
So che il Tempo di esecuzione di Obj-C consente la creazione di classi in RUNTIME, nonché i relativi ivar e metodi.Sono inoltre disponibili per la creazione i SEL.Penso che mi manchi qualcosa, ma qualcuno sa quale funzione chiamare per creare un protocollo in fase di esecuzione?Il motivo principale di ciò è conformsToProtocol:funzionare, quindi la semplice aggiunta dei metodi appropriati non è sufficiente.
Soluzione 2
il seguente tipo di opere, ma a corretto il modo di farlo sarebbe molto apprezzato:
Protocol *proto = [Protocol alloc];
object_setInstanceVariable(proto, "protocol_name", &"mySuperDuperProtocol");
void *nada = NULL;
object_setInstanceVariable(proto, "protocol_list", &nada);
object_setInstanceVariable(proto, "class_methods", &nada);
struct objc_method_description_list *methods;
methods = malloc(sizeof(int) + sizeof(struct objc_method_description) * 1);
methods->count = 1;
methods->list[0].name = @selector(foobar:);
methods->list[0].types = "v:@";
object_setInstanceVariable(proto, "instance_methods", &methods);
class_addProtocol([self class], proto);
NSLog(@"%d %s", [self conformsToProtocol:proto], protocol_getName(objc_getProtocol("mySuperDuperProtocol")));
Il primo parametro NSLog è 1 e non lo è quando la riga che aggiunge il protocollo alla classe è commentata, il che significa che il protocollo È in qualche modo si è registrato alla classe.D'altra parte, non viene restituito da objc_getProtocol (la seconda cosa registrata è nil).
Altri suggerimenti
Modo per aggiungere il protocollo in fase di esecuzione
Protocol *aProtocol = objc_allocateProtocol("TestingRuntimeDelegate");
AppDelegate *appInstance = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(@"conformed Protocol ..%d",class_conformsToProtocol([self.delegate class], aProtocol));
protocol_addMethodDescription(aProtocol, @selector(itIsTestDelegate), "test", NO, NO);
objc_registerProtocol(aProtocol);
class_addProtocol([appInstance class], aProtocol);
//NSLog(@"adding Protocol %d",class_addProtocol([appInstance class], aProtocol));
if ([self.delegate conformsToProtocol:@protocol(TestDelegate)])
{
NSLog(@"conformed Protocol ..");
}
else
{
NSLog(@"conformed Protocol ..%d",class_conformsToProtocol([appInstance class], aProtocol));
class_conformsToProtocol([self.delegate class], aProtocol);
[appInstance performSelector:@selector(itIsTestDelegate)];
}
Ma il metodo delegato deve essere definito in precedenza su quella classe altrimenti si bloccherà a causa del selettore non riconosciuto
oppure il metodo può essere aggiunto in fase di esecuzione..Allora funzionerà bene..
Ma è necessario prima importare il file seguente.
#include <objc/runtime.h>