2011-02-14 34 views
3

我正在写代理对象的RPC实现(想想NSDistantObject)。在执行此操作时,我们直接从服务器实现中生成头文件(包括DTO:和协议)。我在运行时动态地创建对象,但是我遇到了一个特定的问题。如何让我的iPhone应用程序动态加载协议?

当遇到一个对象时,我的名字是一个字符串,我从那里弄清楚如何处理它。当我试图“查询”系统中没有在代码中任何地方使用的协议时,我的问题就会出现。头文件在那里,甚至#import:编。

一些例子...

这个伟大的工程:

Protocol *protocol = NSProtocolFromString(@"UIApplicationDelegate"); // Returns a protocol 

如果我把我自己的协议之一,并指定我的应用程序委托应遵守它,它也可以没有任何问题:

@interface ApplicationDelegate : NSObject <UIApplicationDelegate, ACMyCustomProtocol> { 

} 

// Implementation... 

Protocol *protocol = NSProtocolFromString(@"ACMyCustomProtocol"); // Returns a protocol 

但是,如果我问一个协议,这在我的项目没有阶级符合,我得到nil

Protocol *protocol = NSProtocolFromString(@"ACMyCustomProtocolNotMentionedAnywhere"); // Returns nil 

我试着改变了构建配置(认为Xcode可能会在构建时剥离未使用的代码)而没有运气。也试过Protocol *objc_getProtocol(const char *name)没有运气。

编辑:

我从在开发者论坛是一种用户小费,不幸的是,这可能意味着我的运气。被声明但不 使用(除了类型检查如下所述 )

The Objective-C Programming Language: Protocols

协议不被在运行时 协议对象表示。

+0

为什么你需要让你的应用程序不使用的协议地方? – JeremyP 2011-02-14 16:54:39

+0

我在运行时创建代理对象,使它们符合我的预定义协议。这些协议反过来充当模板,以便在服务器上调用哪些方法(实际上是服务器上的相应对象)。所以我使用这些协议,但我没有定义在头文件中使用它们的类。我的想法是用`BOOL class_addProtocol(Class cls,Protocol * protocol)`将协议添加到我的远程对象中,但由于我无法创建任何`Protocol *`对象,所以我运气不好。 – alleus 2011-02-14 21:26:23

回答

4

由于您的协议#import版,简单地做一个@protocol(MyProtocolName)在编译的代码的某个地方应该足以确保Protocol对象存在在运行时。也许一个很好的方法是创建一个静态的NSDictionary,从已知协议名称映射到Protocol对象。基本上你会为你的已知协议重新实现NSProtocolFromString,但它保证这些协议对象将被编译。即是这样的:

+ (Protocol)remoteProtocolForName:(NSString *)name 
{ 
    static NSDictionary *dict = nil; 
    if (!dict) 
    { 
     dict = [[NSDictionary alloc] initWithObjectsAndKeys: 
       @protocol(Foo), @"Foo", 
       ...]; 
    } 
    return [dict objectForKey:name]; 
} 

它发生,我现在我不知道,你可以存储Protocol S IN的NSDictionary ...

相关问题