2010-04-11 1 views
3

Прежде всего, я хочу быть ясно, что я не говорю об определении протокола, и я понимаю концепциюКак создать протокол во время выполнения в Objective-C?

@protocol someprotocol 
- (void)method; 
@end 

Я знаю, что Obj-C runtime позволяет создавать классы в RUNTIME, а также как его ивары и методы. Также доступны для создания SEL-s. Я думаю, что я просто что-то пропустил, но кто-нибудь знает, какую функцию вызывать для создания протокола во время выполнения? Основная причина этого заключается в том, что для соответствияToProtocol: работать, поэтому просто добавлять соответствующие методы на самом деле не разрезать.

+1

Я не думаю, что вы можете. Но что вы собираетесь использовать недавно созданный динамически протокол, если это возможно? Зачем вам нужно тестировать класс против динамически генерируемого протокола? – Yuji

+3

im написать переводчик объектива-c: D –

+1

Это очень здорово! – Yuji

ответ

1

следующий вид работ, но правильный способ сделать это было бы оценено:

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

Первый параметр NSLog является 1, а не тогда, когда линия добавления протокола к класс закомментирован, то есть протокол - как-то зарегистрирован в классе. С другой стороны, он не возвращается objc_getProtocol (вторая зарегистрированная запись равна нулю).

8

способ добавить протокол во время выполнения

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

Но метод делегата должен быть предварительно определен в этом классе в противном случае это приведет к краху из-за непризнанный селектор

или метод может быть добавлен во время выполнения. . Тогда он будет работать нормально.

Но сначала необходимо импортировать следующий файл.

#include <objc/runtime.h>