79 votes

Déclarer et vérifier / comparer des énumérations (masque de masque) dans Objective-C

Vous savez dans le Cacao, il y a cette chose, par exemple, vous pouvez créer un UIView et faire:

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

J'ai une coutume UIView avec plusieurs états, que j'ai définie dans un enum comme ceci:

enum DownloadViewStatus {
  FileNotDownloaded,
  FileDownloading,
  FileDowloaded
};

Pour chaque sous-vue, j'ai mis son tag: subview1.tag = FileNotDowloaded;

Ensuite, j'ai un custom définition pour l'affichage de l'état qui effectue les opérations suivantes:

    for (UIView *subview in self.subviews) {
      if (subview.tag == viewStatus)
        subview.hidden = NO;
      else
        subview.hidden = YES;
    }

Mais ce que je suis en train de faire, est de permettre à ceci:

subview1.tag = FileNotDowloaded | FileDownloaded;

Donc, mon subview1 s'affiche dans les deux états de mon point de vue. Actuellement, il ne se trouve pas dans l'un de ces deux états depuis l' | opérateur semble ajouter les deux valeurs enum.

Est-il un moyen de le faire?

281voto

Regexident Points 17722

Déclarer Des Masques De Bits:

Sinon pour affecter des valeurs absolues (1, 2, 4, ...), vous pouvez déclarer des masques de bits (comment on les appelle) comme ceci:

typedef enum : NSUInteger {
  FileNotDownloaded = (1 << 0), // => 00000001
  FileDownloading   = (1 << 1), // => 00000010
  FileDowloaded     = (1 << 2)  // => 00000100
} DownloadViewStatus;

ou, en utilisant les ObjC de l' NS_OPTIONS/NS_ENUM des macros:

typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
  FileNotDownloaded = (1 << 0), // => 00000001
  FileDownloading   = (1 << 1), // => 00000010
  FileDowloaded     = (1 << 2)  // => 00000100
};

(voir Abizern réponse pour plus d'info sur ce dernier)

Le concept des masques de bits est (généralement) définir chaque valeur d'enum avec un seul ensemble de bits.

Par conséquent ORing deux valeurs est le suivant:

DownloadViewStatus status = FileNotDownloaded | FileDowloaded; // => 00000101

ce qui est équivalent à:

  00000001 // FileNotDownloaded
| 00000100 // FileDowloaded
----------
= 00000101 // (FileNotDownloaded | FileDowloaded)

La Comparaison De Masques De Bits:

Une chose à garder à l'esprit lors de la vérification masques de bits:

La vérification exacte de l'égalité:

Supposons que l'état est initialisé comme ceci:

DownloadViewStatus status = FileNotDownloaded | FileDowloaded; // => 00000101

Si vous voulez vérifier si status équivaut FileNotDownloaded, vous pouvez utiliser:

BOOL equals = (status == FileNotDownloaded); // => false

ce qui est équivalent à:

   00000101 // (FileNotDownloaded | FileDowloaded)
== 00000100 // FileDowloaded
-----------
=  00000000 // false

La vérification du mot "membre":

Si vous voulez vérifier si status seulement contient FileNotDownloaded, vous devez utiliser:

BOOL contains = (status & FileNotDownloaded) != 0; // => true

   00000101 // (FileNotDownloaded | FileDowloaded)
&  00000100 // FileDowloaded
-----------
=  00000100 // FileDowloaded
!= 00000000 // 0
-----------
=  00000001 // 1 => true

Voir la subtile différence (et pourquoi votre actuelle "si"-l'expression est probablement faux)?

20voto

Abizern Points 52378

Bien que @Regexident ait fourni une excellente réponse, je dois mentionner la manière moderne, utilisée par Objective-C, de déclarer les options énumérées avec NS_OPTIONS :

 typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
  FileNotDownloaded = 0,
  FileDownloading   = 1 << 0,
  FileDownloaded     = 1 << 1
};
 

Référence supplémentaire:

1voto

mah Points 21457
 enum DownloadViewStatus {
  FileNotDownloaded = 1,
  FileDownloading = 2,
  FileDowloaded = 4
};
 

Cela vous permettra d'effectuer des opérations OU au niveau du bit et de manière efficace.

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