37 votes

lier les catégories d'objective-c dans une bibliothèque statique

Je développe un plugin pour une application iOS. Je le compile dans un fichier .a qui est ensuite utilisé par le projet xcode principal.

Jusqu'à présent, j'ai créé une catégorie de la classe UIDevice dans cette bibliothèque. Lorsque je lance le projet principal en utilisant cette bibliothèque, il se bloque à cause d'un sélecteur non reconnu.

-[Plate-forme UIDevice] : sélecteur non reconnu envoyé à l'instance

La plate-forme est l'une des fonctions que j'ai ajoutées via la catégorie.

J'ai donc pensé qu'il ne reliait pas du tout ces fonctions et j'ai ajouté une fonction c dans le même fichier que la catégorie UIDevice puis je l'ai appelée depuis mon code .

Cette fois, le projet principal a bien fonctionné... Alors j'ai pensé que c'était peut-être quelque chose d'autre que j'ai fait et j'ai supprimé la fonction C. Mais voilà, il a encore planté à cause d'un sélecteur non reconnu...

Mes questions : Pourquoi xcode ignore-t-il la définition de la catégorie à moins que j'appelle une fonction déclarée dans le même fichier ?

Y a-t-il un paramètre xcode que je peux modifier pour que ces méthodes de la catégorie UIDevice soient incluses, que j'appelle une fonction de ce fichier ou non ?

salutations

73voto

albertamg Points 18630

Vérifiez Construire des bibliothèques statiques Objective-C avec des catégories :

Objective-C ne définit pas de symboles de linker pour chaque fonction (ou méthode, en Objective-C) - au lieu de cela, les symboles de liaison sont uniquement générés pour chaque classe. Si vous étendez une classe préexistante avec des catégories, le linker ne sait pas associer le code objet de l'implémentation de la classe principale et de l'implémentation de la catégorie. Cela empêche les objets créés dans l'application résultante de répondre à un sélecteur qui est défini dans la catégorie.

Pour résoudre ce problème, la liaison cible contre la bibliothèque statique doit passer l'option -ObjC à l'éditeur de liens. Ce drapeau fait en sorte que l'éditeur de liens de charger chaque fichier objet de la bibliothèque qui définit une classe ou une catégorie Objective-C ou une catégorie. Bien que cette option donne généralement lieu à un exécutable plus volumineux (en raison du code objet supplémentaire chargé dans l'application), elle permet de créer des applications efficaces. l'application), elle permet de créer des bibliothèques statiques Objective-C efficaces qui contiennent des catégories sur une seule page. bibliothèques statiques Objective-C qui contiennent des catégories sur des classes existantes.


Important : Pour les applications 64 bits et iPhone OS, il y a une bug du linker qui empêche -ObjC de charger les fichiers d'objets des bibliothèques statiques qui ne contiennent que des catégories et aucune classe. La solution de contournement est d'utiliser les drapeaux -all_load ou -force_load.

Source : @albertamg ( lier les catégories d'objective-c dans une bibliothèque statique )

8voto

J'ai eu le même problème. Une méthode définie dans une catégorie définie dans un sous-projet a donné lieu à une exception de sélecteur non reconnu. (En fait, cela s'est manifesté par l'impossibilité de spécifier une sous-classe UILabel dans Interface Builder ; le XIB contenait la classe affichée dans IB (UILabel ou UIView, selon ce que j'y ai glissé), plutôt que la classe que j'ai tapée, et cela ressemblait à un bogue bizarre de XCode).

La solution qui a fonctionné pour moi a été d'utiliser -force_load :

Dans le panneau de gauche, sélectionnez votre projet principal (l'élément Root). Sur la droite, vous verrez PROJECT y TARGETS . Sélectionnez TARGETS . Allez à "Build Settings" (dans la barre supérieure) -- "Linking" -- "Other linker flags" et, en supposant que votre sous-projet s'appelle XXXXX, ajoutez -force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a (l'élément a deux sous-éléments, Debug et Release, mais vous cliquez sur cet élément composé pour que cela affecte à la fois Debug et Release).

Notez que -force_load fonctionne pour une seule bibliothèque, et vous devrez peut-être spécifier un -force_load distinct pour chaque bibliothèque de sous-projet.

-1voto

Binh Le Points 143

J'ai eu ce problème et j'ai passé près d'une heure à le résoudre. Dieu merci, c'est fait. Les méthodes qui sont définies doivent être de type statique !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X