Sie wissen, dass es in Cocoa dieses Ding gibt, zum Beispiel können Sie ein erstellen UIView
und tun:
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Ich habe einen Brauch UIView
mit mehreren Zuständen, den ich folgendermaßen definiert enum
habe:
enum DownloadViewStatus {
FileNotDownloaded,
FileDownloading,
FileDownloaded
};
Für jede erstellte Unteransicht setze ich Folgendes tag
:subview1.tag = FileNotDownloaded;
Dann habe ich einen benutzerdefinierten Setter für den Ansichtsstatus, der Folgendes ausführt:
for (UIView *subview in self.subviews) {
if (subview.tag == viewStatus)
subview.hidden = NO;
else
subview.hidden = YES;
}
Aber was ich versuche zu tun , ist dies zuzulassen:
subview1.tag = FileNotDownloaded | FileDownloaded;
Also subview1
taucht meine in zwei Zuständen meiner Ansicht nach auf. Derzeit wird es in keinem dieser beiden Zustände |
angezeigt , da der Operator die beiden Aufzählungswerte zu addieren scheint.
Gibt es eine Möglichkeit, das zu tun?
(subview.tag == viewStatus)
Aussehen falsch zu mir. Sollte sein((subview.tag & viewStatus) != 0x0)
, es sei denn, Sie möchten nur die genaue Übereinstimmung überprüfen. In diesem Fall würden Sie überhaupt keine Bitmaske benötigen, sondern nur eine einfache alte Aufzählung. Siehe zweite Hälfte meiner Antwort.Antworten:
Bitmasken deklarieren:
Alternativ absolute Werte zuweisen (
1
,2
,4
, ...) können Sie erklären Bitmasken (wie diese genannt werden) wie folgt aus :typedef enum : NSUInteger { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 } DownloadViewStatus;
oder mit modernen ObjCs
NS_OPTIONS
/NS_ENUM
Makros:typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 };
( Weitere Informationen zu letzterem finden Sie in Abizerns Antwort. )
Das Konzept von Bitmasken besteht darin, (normalerweise) jeden Aufzählungswert mit einem einzelnen Bitsatz zu definieren.
Daher
OR
ergibt zwei Werte Folgendes:DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
was äquivalent ist zu:
00000001 // FileNotDownloaded | 00000100 // FileDownloaded ---------- = 00000101 // (FileNotDownloaded | FileDownloaded)
Bitmasken vergleichen:
Eine Sache, die Sie bei der Überprüfung gegen Bitmasken beachten sollten:
Überprüfung auf genaue Gleichheit:
Nehmen wir an, dass der Status folgendermaßen initialisiert wird:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
Wenn Sie überprüfen möchten, ob
status
gleich istFileNotDownloaded
, können Sie Folgendes verwenden:BOOL equals = (status == FileNotDownloaded); // => false
was äquivalent ist zu:
00000101 // (FileNotDownloaded | FileDownloaded) == 00000100 // FileDownloaded ----------- = 00000000 // false
Überprüfung auf "Mitgliedschaft":
Wenn Sie überprüfen möchten, ob es
status
nur enthältFileNotDownloaded
, müssen Sie Folgendes verwenden:BOOL contains = (status & FileNotDownloaded) != 0; // => true 00000101 // (FileNotDownloaded | FileDownloaded) & 00000100 // FileDownloaded ----------- = 00000100 // FileDownloaded != 00000000 // 0 ----------- = 00000001 // 1 => true
Sehen Sie den subtilen Unterschied (und warum ist Ihr aktueller "Wenn" -Ausdruck wahrscheinlich falsch)?
quelle
FileNotDownloaded = (0x1 << 0), // => %...00000001
usw.NS_OPTIONS
Vollständigkeit halber wurde eine Variation mit hinzugefügt .Während @Regexident eine hervorragende Antwort geliefert hat, muss ich die moderne Objective-C-Methode zur Deklaration von aufgezählten Optionen erwähnen mit
NS_OPTIONS
:typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) { FileNotDownloaded = 0, FileDownloading = 1 << 0, FileDownloaded = 1 << 1 };
Weitere Referenz:
quelle
enum DownloadViewStatus { FileNotDownloaded = 1, FileDownloading = 2, FileDowloaded = 4 };
Auf diese Weise können Sie bitweise ODERs und UNDs effektiv ausführen.
quelle
1 << 0
,1 << 1
,1 << 2
etc. Dies macht deutlich , Sie mit Bits und Masken arbeiten.Nützliche Funktion, die Sie zur Bitmaskenprüfung verwenden können, um die Lesbarkeit zu verbessern.
BOOL bitmaskContains(NSUInteger bitmask, NSUInteger contains) { return (bitmask & contains) != 0; }
quelle
(bitmask & contains) == contains
- es wird sogar mit Nullcontains