2016-05-06 10 views
1

Der allgemeine Standard scheint NS_ENUM mit NSInteger als Basistyp zu verwenden. Warum ist das der Fall? Unter der Annahme von weniger als 256 Fällen (was fast jede Aufzählung abdeckt) gibt es einen Grund, das anstelle von uint8_t zu verwenden, was weniger Speicherplatz belegen könnte? Entweder importiert in Swift gut.Gibt es einen Grund, NSInteger statt uint8_t mit NS_ENUM zu verwenden?

Dies ist anders als NS_OPTIONS, wo ein größerer Typ sinnvoll ist, da Sie mit Enumerationen kein bisschen Mathe machen sollten, und Sie können jede durch den Basistyp darstellbare Zahl als Wert verwenden.

Antwort

2

Die Antwort auf die Frage im Titel:

Gibt es einen Grund NSInteger zu verwenden, anstatt uint8_t mit NS_ENUM?

ist wahrscheinlich nicht.

Wenn eine ENUM in C erklärt, wenn kein zugrunde liegenden Typ angegeben wird der Compiler jeden geeigneten Typ von char und die mit und ohne Vorzeichen integer-Typen, die zumindest alle erforderlich, um die Werte darstellen kann wählen frei ist. Der aktuelle Xcode/Clang-Compiler wählt eine 4-Byte-Ganzzahl aus. Man könnte vernünftigerweise annehmen, dass die Autoren des Compilers eine informierte Entscheidung getroffen haben - ein gewisses Gleichgewicht zwischen Leistung und Speicher.

Kleinere Typen, wie z. B. uint8_t, werden normalerweise auf kleinere Grenzen im Speicher (oder auf der Platte) ausgerichtet - aber das ist nur von Vorteil, wenn das angrenzende Feld der Ausrichtung z. Wenn ein typisiertes Feld mit einer Größe von 2 Byte einem typisierten Feld mit einer Größe von 1 Byte folgt, wird, wenn nicht anders angegeben (z. B. mit einem #pragma packed), wahrscheinlich ein dazwischenliegendes unbenutztes Byte vorhanden sein.

Ob Leistung oder Speicherunterschiede signifikant sind, hängt stark von der Anwendung ab. Befolgen Sie die übliche Faustregel - optimieren Sie nicht, bis ein Problem gefunden wird.

Wenn Sie jedoch semantische Nutzen in der Begrenzung der Größe dann sicherlich tun - es gibt keinen allgemeinen Grund, warum Sie nicht sollten. Die Auswahl ist ähnlich wie das Auswählen von signierten vs. unsigned Ganzzahlen, einige Programmierer vermeiden vorzeichenlose Typen für Werte, die ≥ 0 sind, sofern sie nicht unbedingt für den zusätzlichen Bereich erforderlich sind, während andere den semantischen Nutzen schätzen.

Zusammenfassung: Es gibt keine richtige Antwort, es ist weitgehend ein subjektives Problem.

HTH

+0

Nur eine kleine Bemerkung: * from char und die vorzeichenbehafteten und vorzeichenlosen Integer-Typen * 'char' ist ein Integer-Typ. –

+0

@ AminNegm-Awad - True, und es ist wichtig, sich daran zu erinnern. Es ist jedoch kein * signed integer type * oder * vorzeichenloser integer type *. Die Liste für "enum" oben ist, was in der C-Norm gegeben ist: "Jeder aufgezählte Typ soll mit' char', einem vorzeichenbehafteten Integer-Typ oder einem vorzeichenlosen Integer-Typ kompatibel sein. " Der Standard verwendet hier nicht den Integer-Typ selbst, da dieser Begriff wie folgt definiert ist: "Der Typ' char', die Integer-Typen mit und ohne Vorzeichen und die Aufzählungstypen werden zusammen als * Integer-Typen * "; und der zugrunde liegende Typ einer Aufzählung kann keine andere Aufzählung sein. Sind keine Standards Spaß :-) – CRD

+0

Um es lustiger 'signed char' zu machen, ist ein vorzeichenbehafteter Integer-Typ: * Es gibt fünf vorzeichenbehaftete Integer-Typen, bezeichnet als signed char, short int, int, long int und long long int . * Die ganze Geschichte dahinter ist, dass die voreingestellte Signedness od 'char' implementationsdefiniert ist. (Wie Sie sicher wissen, nur für das Protokoll.) Ja, Standards machen Spaß. Ich mag es. :-) –

1

Vor allem: Der Speicherbedarf ist fast völlig bedeutungslos. Sie sprechen über 1 Byte vs. 4/8 Bytes. (Wenn die Speicherausrichtung die Verwendung von 4/8 Bytes nicht erzwingt, was auch immer Sie gewählt haben.) Wie viele NS_ENUM10 (C) Objekte möchten Sie in Ihrer laufenden App haben?

Ich denke, dass der Grund ist ziemlich einfach: NSInteger ist verwandt von "catch all" Integer-Typ in Cocoa. Das erleichtert die Zuweisung, insbesondere müssen Sie keinen größeren Integer-Typ einem kleineren Typ zuweisen. Ohne Casting würde dies zu Warnungen führen.

Wenn Sie mehr als einen Integer-Typ in einer Desktop-App mit einem 32/64-Bit-Modell verwenden, ähnelt dies einem Anachronismus. Auch ein Mac weder ein MacBook weder ein iPhone ist ein Embedded-Mikrocontroller ...

0

Sie können eine beliebige Integer-Datentyp einschließlich uint8_t mit NS_ENUM verwenden können, wie.

typedef NS_ENUM(uint8_t, eEnumAddEditViewMode) { 
    eWBEnumAddMode, 
    eWBEnumEditMode 

};

In alten c-Stil Standard NSInteger ist Standard, weil NSInteger ist verwandt von "catch all" Integer-Typ in Ziel c. und Entwickler können Boxing und Unboxing einfach mit ihrer eigenen Variablen eingeben. Dies ist nur eine entwicklerfreundliche Best Practice.

Verwandte Themen