Vous savez dans Cocoa il y a cette chose, par exemple vous pouvez créer un UIView
et faire:
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
J’ai un UIView
personnalisé avec plusieurs états, que j’ai défini dans un enum
comme ceci:
enum DownloadViewStatus { FileNotDownloaded, FileDownloading, FileDownloaded };
Pour chaque sous-vue créée, j’ai défini sa tag
: subview1.tag = FileNotDownloaded;
Ensuite, j’ai un setter personnalisé pour l’état d’affichage 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 j’essaie de faire , c’est de permettre ceci:
subview1.tag = FileNotDownloaded | FileDownloaded;
Donc, mon sous- subview1
apparaît dans deux états de ma vue. Actuellement, il ne figure dans aucun de ces deux états depuis le |
l’opérateur semble append les deux valeurs enum.
Y-a-t-il un moyen de faire ça?
Alternativement, vous pouvez atsortingbuer des valeurs absolues ( 1
, 2
, 4
,…) comme ceci:
typedef enum : NSUInteger { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 } DownloadViewStatus;
ou en utilisant les macros modernes NS_OPTIONS
/ NS_ENUM
:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 };
(voir la réponse d’ Abizern pour plus d’informations sur ce dernier)
Le concept de bitmasks consiste à (généralement) définir chaque valeur enum avec un seul bit défini.
Ainsi, deux valeurs OR
effectuent les opérations suivantes:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
ce qui équivaut à:
00000001 // FileNotDownloaded | 00000100 // FileDownloaded ---------- = 00000101 // (FileNotDownloaded | FileDownloaded)
Une chose à garder à l’esprit lors de la vérification contre les masques de bits:
Supposons que le statut est initialisé comme ceci:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
Si vous voulez vérifier si le status
est égal à FileNotDownloaded
, vous pouvez utiliser:
BOOL equals = (status == FileNotDownloaded); // => false
ce qui équivaut à:
00000101 // (FileNotDownloaded | FileDownloaded) == 00000100 // FileDownloaded ----------- = 00000000 // false
Si vous voulez vérifier si le status
contient simplement FileNotDownloaded
, vous devez utiliser:
BOOL contains = (status & FileNotDownloaded) != 0; // => true 00000101 // (FileNotDownloaded | FileDownloaded) & 00000100 // FileDownloaded ----------- = 00000100 // FileDownloaded != 00000000 // 0 ----------- = 00000001 // 1 => true
Voir la différence subtile (et pourquoi votre expression “if” actuelle est probablement incorrecte)?
Alors que @Regexident a fourni une excellente réponse – je dois mentionner la manière moderne d’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:
enum DownloadViewStatus { FileNotDownloaded = 1, FileDownloading = 2, FileDowloaded = 4 };
Cela vous permettra d’exécuter efficacement des OR et des AND au niveau du bit.