2011-02-14 5 views
3

J'écris une implémentation RPC avec des objets proxy (pensez à NSDistantObject). Ce faisant, nous générons des fichiers d'en-tête (DTO: s et protocoles) directement à partir de l'implémentation du serveur. Je crée des objets dynamiquement en cours d'exécution, mais j'ai rencontré un problème spécifique. Lorsque je rencontre un objet, j'ai le nom sous la forme d'une chaîne, et à partir de là, je vois ce que je veux en faire. Mon problème apparaît lorsque je tente d'interroger le système pour un protocole qui n'est utilisé nulle part dans le code. Le fichier d'en-tête est là, même #import: ed.Comment puis-je faire en sorte que mon application iPhone charge les protocoles de façon dynamique?

Quelques exemples ...

Cela fonctionne très bien:

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

Si je prends un de mes propres protocoles et précise que mon délégué application doit se conformer à elle, elle fonctionne également sans aucun problème:

@interface ApplicationDelegate : NSObject <UIApplicationDelegate, ACMyCustomProtocol> { 

} 

// Implementation... 

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

Mais si je demande un protocole, qui ne classe dans mon projet est conforme à, je reçois nil:

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

J'ai essayé de changer la configuration de construction (supposé que Xcode supprime peut-être le code inutilisé lors de la construction) sans aucune chance. Également essayé Protocol *objc_getProtocol(const char *name) sans chance.

Edit:

Je suis une pointe d'un utilisateur de type sur les forums de développeurs, malheureusement, cela signifie probablement que je suis hors de la chance.

The Objective-C Programming Language: Protocols

Les protocoles qui sont déclarés mais non utilisés (sauf pour le type de vérification que décrit ci-dessous) ne sont pas représentés par objets du protocole lors de l'exécution.

+0

Pourquoi avez-vous besoin d'obtenir un protocole que votre application n'utilise pas nulle part? – JeremyP

+0

Je crée des objets proxy à l'exécution, en les conformant à mes protocoles prédéfinis. Les protocoles agissent à leur tour comme des modèles pour quelles méthodes peuvent être appelées sur le serveur (en pratique, les objets correspondants sur le serveur). J'utilise donc les protocoles, mais je n'ai aucune classe définie pour les utiliser dans le fichier d'en-tête. Mon idée était d'ajouter les protocoles à mes objets distants avec 'BOOL class_addProtocol (classe cls, Protocol * protocol)', mais comme je ne peux pas créer d'objets 'Protocol *', je n'ai pas de chance. – alleus

Répondre

4

Étant donné que vos protocoles sont #import ed, faisant simplement une @protocol(MyProtocolName) quelque part dans le code compilé devrait être suffisant pour vous assurer que l'objet existe Protocol lors de l'exécution. Peut-être un bon moyen de le faire est de créer un NSDictionary statique qui mappe des noms de protocole connus aux objets Protocol. Fondamentalement, vous réimplémenterez NSProtocolFromString pour vos protocoles connus, mais cela garantit que ces objets de protocole seront compilés. C'est à dire. quelque chose comme:

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

Il me maintenant que je ne suis pas sûr que vous pouvez stocker Protocol s dans un NSDictionary ...

+0

Je suis allé pour une solution similaire.J'ai juste un fichier d'implémentation séparé avec une méthode fictive (jamais même appelée) avec tous les protocoles mentionnés (avec juste @protocol (Foo); @protocol (Bar); ... ' – alleus

Questions connexes