web-dev-qa-db-fra.com

Relier des catégories Objective-C dans une bibliothèque statique

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

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

- [Plate-forme Uidevice]: Sélecteur non reconnu envoyé à l'instance

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

Je pensais donc que ce n'était pas un lien entre ces fonctions et ajouté une fonction C au même fichier que la catégorie Uidevice l'a ensuite appelée à partir de mon code.

Cette fois, le projet principal courait bien ... Je pensais peut-être que c'était peut-être autre chose que j'ai fait et supprimé la fonction C. Mais lo et voici, il s'est encore écrasé en raison d'un sélecteur non reconnu ..

Mes questions: Pourquoi Xcode ignore-t-il la définition de catégorie à moins d'appeler une fonction déclarée dans le même dossier?

Existe-t-il un paramètre Xcode que je peux changer pour que cela inclut ces méthodes de la catégorie Uidevice, que j'appelle une fonction de ce fichier ou non?

tchin Tchin

37
micken

Vérifiez Building Objective-C Bibliothèques statiques avec catégories :

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

Pour résoudre ce problème, la liaison ciblée contre la bibliothèque statique doit passer l'option -OBJC sur la liaison. Ce drapeau provoque la chargement de chaque fichier d'objet. dans la bibliothèque qui définit une classe ou une catégorie de l'objectif-C. Bien que cette option aboutira généralement à une exécutable plus grande (en raison du code d'objet supplémentaire chargé dans l'application), il permettra de créer une création réussie de bibliothèques statiques de l'objectif-C efficaces qui contiennent des catégories sur les classes existantes.


Important : Pour les applications OS 64 bits et iPhone, il existe un bug de liaison qui empêche -OBJC de charger des fichiers d'objets à partir de bibliothèques statiques contenant uniquement des catégories et Pas de classes. La solution de contournement doit utiliser les drapeaux -all_load ou -force_load.

Source: @Albertamg ( Liaison Catégories de l'objectif-C dans une bibliothèque statique )

72
albertamg

J'ai eu le même problème. Une méthode définie dans une catégorie définie dans un sous-projet a abouti à une exception de sélecteur non reconnue. (En fait, cela se manifeste comme incapacité à spécifier une sous-classe Uilabel dans Builder d'interface; le XIB contenait la classe indiquée dans IB (Uilabel ou UIView, selon ce que j'ai traîné là), plutôt que la classe que j'ai saisie, et que regardé comme un bug xcode étrange.)

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 racine). À droite, vous verrez PROJECT et TARGETS. Sélectionnez TARGETS. Allez à "Construire les paramètres" (dans la barre supérieure) - "Liaison" - "Autres drapeaux de liaison" et, en supposant que votre sous-projet soit appelé xxxxx, ajoutez -force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a Là (l'article dispose de deux sous-éléments, de débogage et de libération, mais vous cliquez sur cet élément composé de manière à ce que, s'ils affectent à la fois la débogage et la libération).

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

8