Question

First of all, I want to be clear that I'm not talking about defining a protocol, and that I understand the concept of

@protocol someprotocol
- (void)method;
@end

I know that the Obj-C runtime allows creation of classes at RUNTIME, as well as its ivars and methods. Also available for creation are SEL-s. I think I'm just missing something, but does anyone know what function to call to create a protocol at runtime? The main reason for this is for conformsToProtocol: to work, so just adding the appropriate methods doesn't really cut it.

Was it helpful?

Solution 2

the following sort of works, but a proper way of doing this would be much appreciated:

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")));

The first NSLog parameter is 1, and isn't when the line adding the protocol to the class is commented out, meaning the protocol is somehow registered with the class. On the other hand, it does not get returned by objc_getProtocol (the second thing logged is nil).

OTHER TIPS

Way to add protocol at runtime

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)];
}

But the delegate method must be previously defined on that class otherwise it will crash due to unrecognized selector

or the method can be added at run time.. Then it will work fine..

But the following file must be imported first.

#include <objc/runtime.h>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top