objective c - ما هو التعداد typedef في Objective-C؟




enums (9)

لا أعتقد أنني أفهم بشكل أساسي ما هو enum ، ومتى يستخدمه.

فمثلا:

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

ما الذي يتم الإعلان عنه هنا بالفعل؟


التعداد هو نوع بيانات المعرفة من قبل المستخدم. أﻧواع اﻟﺑﯾﺎﻧﺎت اﻟﻣُﺗﻌﺛرة ﻻ ﯾﻣﮐن أن ﺗﻔﺗرض ﻣﺗﻐﯾرات ﻧوع اﻟﺑﯾﺎﻧﺎت اﻟﻣﺗوﺳطﺔ إﻻ اﻟﻘﯾم اﻟﺗﻲ ﺗم اﻹﻋﻼن ﻋﻧﮭﺎ ﺳﺎﺑﻘﺎً.

enum month { jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec };
enum month this_month;

this_month = feb;

في الإعلان المذكور أعلاه ، يتم الإعلان عن الشهر كنوع بيانات تم تعداده. يتكون من مجموعة من القيم ، jan إلى dec. عدديًا ، يتم إعطاء jan القيمة 1 ، feb القيمة 2 ، وهكذا.

يتم تعريف المتغير this_month من نفس نوع الشهر ، ثم يتم تعيين القيمة المرتبطة بـ feb. لا يمكن تعيين أي قيمة خارج هذا التاريخ المحدد في قائمة التهيئة لإعلان الشهر.


توصي Apple بتعريف التعدادات بهذا الشكل منذ Xcode 4.4:

typedef enum ShapeType : NSUInteger {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

كما أنها توفر ماكرو NS_ENUM مفيدًا:

typedef NS_ENUM(NSUInteger, ShapeType) {
    kCircle,
    kRectangle,
    kOblateSpheroid
};

توفر هذه التعريفات فحصًا أقوى للنوع وإتمامًا أكيدًا للشفرة. لم أتمكن من العثور على وثائق رسمية لـ NS_ENUM ، ولكن يمكنك مشاهدة فيديو "Modern Objective-C" من WWDC 2012 session here .

استكمال: وصلة لوثائق رسمية here .


و Typedef هي الكلمة في C و C ++. يتم استخدامه لإنشاء أسماء جديدة لأنواع البيانات الأساسية (char، int، float، double، struct & enum) .

typedef enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} ShapeType;

هنا يخلق نوع البيانات التي تم تعدادها ShapeType ويمكننا كتابة أسماء جديدة لنوع التعداد ShapeType كما هو موضح أدناه

ShapeType shape1; 
ShapeType shape2; 
ShapeType shape3;

يتم استخدام التعداد (اختصار التعداد) تعداد مجموعة من القيم (عدادين). القيمة هي أي شيء تجريدي يمثله رمز (كلمة). على سبيل المثال ، يمكن أن يكون التعداد الأساسي

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };

يسمى هذا التعداد المجهول لأنه ليس لديك رمز لتسمية ذلك. لكنها ما زالت صحيحة تمامًا. فقط استخدمها هكذا

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;

حسنا. الحياة جميلة وكل شيء يسير على ما يرام. ولكن في يوم من الأيام تحتاج إلى إعادة استخدام هذا التعداد لتحديد متغير جديد لتخزين myGrandFatherPantSize ، ثم تكتب:

enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;

ولكن بعد ذلك يكون لديك خطأ مترجم "redefinition of enumerator". في الواقع المشكلة هي أن المترجم ليس متأكدا من أن التعداد الأول والثاني تصف نفس الشيء.

ثم إذا كنت ترغب في إعادة استخدام نفس مجموعة العدادين (هنا xs ... xxxxl) في عدة أماكن يجب عليك وضع علامة عليه باسم فريد. في المرة الثانية التي تستخدم فيها هذه المجموعة ، عليك فقط استخدام العلامة. ولكن لا تنسَ أن هذه العلامة لا تحل محل كلمة التعداد ، بل مجموعة العدادين فقط. ثم الحرص على استخدام التعداد كالمعتاد. مثله:

// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize; 
// here the second use of my enum. It works now !
enum sizes myGrandFatherPantSize;

يمكنك استخدامه في تعريف المعلمة أيضًا:

// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;

يمكنك القول أن إعادة كتابة التعداد في كل مكان ليس مناسبًا ويجعل الشفرة تبدو غريبة بعض الشيء. أنت محق. نوع حقيقي سيكون أفضل.

هذه هي الخطوة النهائية لتقدمنا ​​الكبير للقمة. بمجرد إضافة الرموز المميزة لـ typedef ، لنقم بتحويل التعداد الخاص بنا بنوع حقيقي. يا شيء آخر ، لا يسمح typedef داخل صفك. ثم حدد نوعك أعلاه فقط. افعلها هكذا:

// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type

@interface myClass {
   ...
   size_type myGrandMotherDressSize, myGrandFatherPantSize;
   ...
}

تذكر أن العلامة اختيارية. بعد ذلك هنا في هذه الحالة ، نحن لا نضع علامات على العدادين ولكن فقط لتحديد نوع جديد. إذن لا نحتاج بعد الآن

// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;

@interface myClass : NSObject {
  ...
  size_type myGrandMotherDressSize, myGrandFatherPantSize;
  ...
}
@end

إذا كنت تقوم بالتطوير في ObjectiveC باستخدام XCode ، فأنت تسمح لك باكتشاف بعض وحدات الماكرو الرائعة مسبقة بـ NS_ENUM. من المفترض أن يساعدك ذلك على تحديد التعدادات الجيدة بسهولة ، وعلاوة على ذلك سيساعد المحلل الساكن على إجراء بعض الاختبارات الشيقة لك قبل التجميع.

التعداد الجيد!


يستخدم التعداد لتعيين قيمة لعناصر التعداد التي لا يمكن القيام به في البنية. لذا في كل مرة بدلاً من الوصول إلى المتغير الكامل ، يمكننا القيام بذلك من خلال القيمة التي نخصصها للمتغيرات في التعداد. يبدأ بشكل افتراضي بـ 0 تعيين ولكن يمكننا تعيين أي قيمة له وسيتم تعيين القيمة التالية في قيمة التعداد التالي في التعداد بقيمة +1 السابقة.


يسمح typedef للمبرمج بتعريف أحد أنواع Objective-C كآخر. فمثلا،

typedef int عداد ؛ يعرّف نوع Counter ليكون مكافئًا لنوع int. هذا بشكل كبير يحسن قراءة التعليمات البرمجية.


يمكنك استخدام التنسيق أدناه ، قيمة افتراضية الخام تبدأ من 0 ، لذلك

  • kCircle هو 0 ،
  • kRectangle عبارة عن 1 ،
  • kOblateSpheroid هو 2.

يمكنك تعيين قيمة البدء الخاصة بك.

typedef enum : NSUInteger {
    kCircle, // for your value; kCircle = 5, ...
    kRectangle,
    kOblateSpheroid
} ShapeType;

ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0

typedef مفيد لإعادة تعريف اسم نوع متغير موجود. يوفر طريقة قصيرة وذات مغزى لاستدعاء نوع بيانات. على سبيل المثال:

typedef unsigned long int TWOWORDS;

هنا ، يتم تعريف النوع long unsigned long لتكون من النوع TWOWORDS. وهكذا ، يمكننا الآن أن نعلن عن متغيرات من النوع غير الموقعة طويلة بالكتابة ،

TWOWORDS var1, var2;

بدلا من

unsigned long int var1, var2;

typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;

ثم يمكنك استخدامه مثل: -

 ShapeType shape;

و

 enum {
    kCircle,
    kRectangle,
    kOblateSpheroid
} 
ShapeType;

الآن يمكنك استخدامه مثل: -

enum ShapeType shape;




typedef