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 son tag
: subview1.tag = FileNotDownloaded;
Ensuite, j'ai un setter personnalisé pour l'état d'affichage qui fait ce qui suit:
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;
Alors mon subview1
apparaît dans deux états de mon point de vue. Actuellement, il n'apparaît dans aucun de ces deux états depuis le |
L'opérateur semble ajouter les deux valeurs d'énumération.
Y-a-t-il un moyen de faire ça?
Vous pouvez également attribuer des valeurs absolues (1
, 2
, 4
,…), Vous pouvez déclarer bitmasks (comment ils sont appelés) comme ceci:
typedef enum : NSUInteger {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
} DownloadViewStatus;
ou en utilisant les macros NS_OPTIONS
/NS_ENUM
d'ObjC modernes:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
};
(voir réponse d'Abizern pour plus d'informations sur ce dernier)
Le concept des masques de bits est de définir (généralement) chaque valeur d'énumération avec un seul ensemble de bits.
Par conséquent, OR
ing deux valeurs effectue 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 des masques de bit:
Supposons que le statut soit initialisé comme ceci:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
Si vous voulez vérifier si 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 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 subtile différence (et pourquoi votre expression "si" actuelle est probablement fausse)?
Alors que @Regexident a fourni une excellente réponse - je dois mentionner la manière moderne 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:
Fonction utile que vous pouvez utiliser pour la vérification du masque de bits pour améliorer la lisibilité.
BOOL bitmaskContains(NSUInteger bitmask, NSUInteger contains) {
return (bitmask & contains) != 0;
}
enum DownloadViewStatus {
FileNotDownloaded = 1,
FileDownloading = 2,
FileDowloaded = 4
};
Cela vous permettra d'effectuer efficacement les OR et ET au niveau du bit.