Question

Je vais avoir des problèmes avec la visibilité ENUM dans un programme Objective-C. J'ai deux fichiers d'en-tête, et on définit un typedef enum. Un autre fichier doit utiliser le type typedef'd.

En C droite, je voudrais simplement #include l'autre fichier d'en-tête, mais en Objective-C, il est recommandé de ne pas utiliser #import entre les fichiers d'en-tête, au lieu d'utiliser des déclarations avant de @class au besoin. Cependant, je ne peux pas comprendre comment avant-déclarer un type d'énumération.

Je ne ai pas besoin l'une des valeurs réelles, sauf dans le fichier de mise en œuvre de .m correspondant, où je peux en toute sécurité #import loin. Alors, comment puis-je obtenir le typedef enum à reconnaître dans l'en-tête?

Était-ce utile?

La solution

Allez-y et utilisez #import. Les seules personnes de raison recommandent d'utiliser @class lorsque cela est possible est parce qu'elle rend votre code un peu plus rapide à compiler. Cependant, il n'y a pas de problème avec #importing un fichier .h d'un autre. En fait, vous devez le faire lors de l'extension une autre classe.

Autres conseils

La façon la plus récente (Swift 3, mai 2017) de transmettre déclarer la ENUM (NS_ENUM / NS_OPTION) en c objectif est d'utiliser les éléments suivants:

// Forward declaration for XYZCharacterType in other header say XYZCharacter.h
typedef NS_ENUM(NSUInteger, XYZCharacterType);


// Enum declaration header: "XYZEnumType.h"
#ifndef XYZCharacterType_h
#define XYZCharacterType_h

typedef NS_ENUM(NSUInteger, XYZEnumType) {
    XYZCharacterTypeNotSet,
    XYZCharacterTypeAgent,
    XYZCharacterTypeKiller,
};

#endif /* XYZCharacterType_h */`

La réponse à votre question est soit aller de l'avant et importer le fichier d'en-tête de typedef ou d'utiliser un type générique comme NSInteger au lieu du type ENUM.

Cependant, il y a plus de raison de ne pas importer un fichier d'en-tête qu'une simple compilation vitesse.

Non importer un fichier d'en-tête réduit également l'accès par inadvertance à des classes étrangères.

Par exemple, supposons que vous avez une classe TrackFileChanges qui suit le système de fichiers pour des modifications à un fichier spécifique, et vous avez une classe CachedFile qui stocke les données mises en cache dans un fichier. Ce dernier pourrait utiliser un Ivar privé de TrackFileChanges de type *, mais pour des utilisations de CachedFile, cela est tout simplement un détail de mise en œuvre (idéalement, le Ivar serait généré automatiquement avec une propriété privée en utilisant le nouveau moteur d'exécution, mais c'est pas possible si vous re en utilisant l'ancien temps d'exécution).

Alors que les clients #import « CachedFile.h » probablement pas besoin ou veulent avoir accès à TrackFileChanges.h. Et s'ils le font, ils devraient préciser qu'elle #importing eux-mêmes. En utilisant @class TrackFileChanges instea de #import "TrackFileChanges.h" dans CachedFile.h vous améliorez l'encapsulation.

Mais tout ce que dit, il n'y a rien awrong avec l'importation d'un fichier d'en-tête d'un second fichier d'en-tête si la deuxième tête veut exposer la première à tous les clients. Par exemple, les fichiers d'en-tête qui déclarent les classes doivent être importés directement dans le sous-classement des fichiers d'en-tête et les fichiers d'en-tête des protocoles pourraient bien déclarant être importés directement (bien que youy peut utiliser @protocol ABC, pour éviter cela).

Si vous êtes ok en utilisant les extensions du compilateur, vous pouvez utiliser cet ordre dans Clang:

enum Enum;
typedef enum Enum Enum2;

void f(Enum2); // ok. it sees this type's true name.

enum Enum {
    E_1
};

// ok. now its declaration is visible and we can use it.

void f(Enum2 e) {

}

Remarque: Il déclenche un avertissement de -Wpedantic

.

Si vous utilisez 11 C ++, vous devez utiliser leurs énumérations, qui sont sûrs de transmettre déclarer - par exemple enum class Enum:uint8_t; (pas une extension du compilateur).

Ce qui a fonctionné pour une déclaration avant d'un ENUM pour moi dans un objectif C .h fichier a été regarder dans le fichier ProjectName-Swift.h et voir ce qu'il dit, qui se trouvait être le suivant:

enum SwiftEnumName: NSInteger;

Je avais besoin de cette déclaration avant parce que j'avais un type de paramètre de fonction de SwiftEnumName. Et il ne me laisse pas mettre l'importation ProjectName-Swift.h dans l'objectif fichier C .h.

Ensuite, dans le Objective C .m Je viens d'avoir le #import "ProjectName-Swift.h" dans et juste utilisé le SwiftEnum normalement.

utilisait Swift 4.1.2.

Il faudrait soit #import eux de toute façon ou créer un fichier d'en-tête distinct contenant uniquement typedef. Pas d'en-tête d'importer des fichiers dans un en-tête rend la compilation plus rapide, mais ne change rien d'autre.

Pourquoi ne supporte pas les ++ C déclaration avant de énumérations?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top