উদ্দেশ্য-সি টাইপিডেফকে তার স্ট্রিং সমতলে রূপান্তর করুন


141

ধরে নিলাম যে আমার .h ফাইলে আমার কাছে টাইপিডেফ ঘোষণা হয়েছে:

typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;

আমি এমন একটি ফাংশন তৈরি করতে চাই যা টাইপডেফের সংখ্যাসম্যকে স্ট্রিংয়ে রূপান্তর করে। উদাহরণস্বরূপ, যদি বার্তাটি [self toString:JSON]প্রেরণ করা হত; এটি 'জেএসওএন' ফেরত আসবে।

ফাংশনটি এরকম কিছু দেখায়:

-(NSString *) toString:(FormatType)formatType {
  //need help here
  return [];
}

ঘটনাচক্রে, যদি আমি এই বাক্য গঠন চেষ্টা করি

[self toString:FormatType.JSON];

পদ্ধতিতে টাইপফের মানটি পাস করতে, আমি একটি ত্রুটি পেয়েছি। আমি কী মিস করছি?


ইস্যুটির আরও পরিস্কার সমাধানের জন্য আমার উত্তর stackoverflow.com/questions/6331762/enum-values-to-nsstring-ios এ দেখুন ।
BooTooMany

4
এনামের উপর আমাদের সুইফট ল্যাঙ্গুয়েজে আলিঙ্গন দেওয়া উচিত ।
ইটাচি

@ ক্রেইগ: এখানে সমাধান github.com/ndpiparava/ObjcEnumString
নিতিন

এনামের জন্য কাস্টম গেটরটি কেবল স্ট্রিংয়ে রূপান্তরিত না করেই সমাধানের জন্য স্ট্রিং-কাস্ট ম্যাক্রো অ্যারেটি দেখুন: stackoverflow.com/a/53755377/2057171
অ্যালবার্ট রেনশওয়া

উত্তর:


135

এটি সত্যিকার অর্থেই একটি সি প্রশ্ন, অবজেক্টিভ-সি (যা সি ভাষার সুপারস্টেট) এর সাথে নির্দিষ্ট নয়। সিতে এনামগুলি পূর্ণসংখ্যা হিসাবে উপস্থাপন করা হয়। সুতরাং আপনাকে এমন একটি ফাংশন লিখতে হবে যা একটি এনাম মান দিয়ে একটি স্ট্রিং দেয়। এটি করার অনেকগুলি উপায় রয়েছে। স্ট্রিংগুলির একটি অ্যারের যেমন এনাম মানটি অ্যারে বা মানচিত্রের কাঠামোর সূচক হিসাবে ব্যবহার করা যেতে পারে (উদাহরণস্বরূপ NSDictionary) যা একটি স্ট্রিং কাজের জন্য এনুম মানকে মানচিত্র করে, তবে আমি দেখতে পেলাম যে এই পদ্ধতিগুলি কোনও ফাংশনের মতো পরিষ্কার নয় রূপান্তরটি সুস্পষ্ট করে তোলে (এবং অ্যারে পদ্ধতির, যদিও সর্বোত্তম Cউপায় বিপজ্জনক যদি আপনার এনাম মানগুলি 0 থেকে সংশ্লেষিত না হয়)। এরকম কিছু কাজ করবে:

- (NSString*)formatTypeToString:(FormatType)formatType {
    NSString *result = nil;

    switch(formatType) {
        case JSON:
            result = @"JSON";
            break;
        case XML:
            result = @"XML";
            break;
        case Atom:
            result = @"Atom";
            break;
        case RSS:
            result = @"RSS";
            break;
        default:
            [NSException raise:NSGenericException format:@"Unexpected FormatType."];
    }

    return result;
}

এনাম মানটির JSONসঠিক FormatType.JSONসংশ্লেষ সম্পর্কে আপনার সম্পর্কিত প্রশ্নটি হ'ল আপনি কেবল মান (উদাহরণস্বরূপ ) ব্যবহার করেন, সিট্যাক্স নয়। FormatTypeএকটি টাইপ এবং enum মান (যেমন হয় JSON, XMLইত্যাদি) মান আপনি যে ধরনের দায়িত্ব অর্পণ করতে পারেন।


127

আপনি এটি সহজেই করতে পারবেন না। সি এবং অবজেক্টিভ-সি-তে, এনামগুলি সত্যই কেবল গৌরবান্বিত পূর্ণসংখ্যার ধ্রুবক। আপনাকে নিজের নামের একটি টেবিল তৈরি করতে হবে (বা কিছু প্রিপ্রোসেসর অপব্যবহার সহ)। উদাহরণ স্বরূপ:

// In a header file
typedef enum FormatType {
    JSON,
    XML,
    Atom,
    RSS
} FormatType;

extern NSString * const FormatType_toString[];

// In a source file
// initialize arrays with explicit indices to make sure 
// the string match the enums properly
NSString * const FormatType_toString[] = {
    [JSON] = @"JSON",
    [XML] = @"XML",
    [Atom] = @"Atom",
    [RSS] = @"RSS"
};
...
// To convert enum to string:
NSString *str = FormatType_toString[theEnumValue];

এই পদ্ধতির বিপদটি হ'ল আপনি যদি কখনও এনাম পরিবর্তন করেন তবে আপনাকে নামের অ্যারে পরিবর্তন করতে হবে। কিছু প্রিপ্রোসেসর অপব্যবহারের মাধ্যমে আপনি এই সমস্যাটি সমাধান করতে পারেন, তবে এটি কৃপণ এবং কুরুচিপূর্ণ।

এছাড়াও মনে রাখবেন যে এটি ধরে নিয়েছে আপনার একটি বৈধ এনাম ধ্রুবক রয়েছে। আপনার যদি অবিশ্বস্ত উত্স থেকে পূর্ণসংখ্যার মান থাকে তবে আপনার ধ্রুবকটি বৈধ কিনা তা পরীক্ষা করার পাশাপাশি আপনার এনুমের মধ্যে একটি "অতীত সর্বোচ্চ" মান অন্তর্ভুক্ত করে বা এটি অ্যারের দৈর্ঘ্যের চেয়ে কম কিনা তা পরীক্ষা করে দেখতে হবে sizeof(FormatType_toString) / sizeof(FormatType_toString[0])


37
আপনি সুস্পষ্ট সূচী দিয়ে অ্যারেগুলি শুরু করতে পারেন, উদাহরণস্বরূপ, string[] = { [XML] = "XML" }স্ট্রিংগুলি enumsগুলির সাথে সঠিকভাবে মেলে তা নিশ্চিত করার জন্য
ক্রিস্টোফ

@Christoph: হ্যাঁ, যে একটি C99 বৈশিষ্ট্য নামক মনোনীত initializers । অবজেক্টিভ-সি (এটি সি 99 এর ভিত্তিতে তৈরি) ব্যবহার করা ভাল, তবে জেনেরিক সি 89 কোডের জন্য আপনি সেগুলি ব্যবহার করতে পারবেন না।
অ্যাডাম রোজেনফিল্ড

অন্য পথে যাওয়ার কোনও উপায় আছে কি? উদাহরণস্বরূপ, এনামকে আবার স্ট্রিং দেওয়া হবে?
জামেও

1
@ জামেও: হ্যাঁ, তবে এটি অ্যারে অনুসন্ধান করার মতো সহজ নয়। হয় আপনাকে FormatType_toString[]অ্যারের মাধ্যমে পুনরাবৃত্তি করতে হবে এবং -isEqualToString:ম্যাচ সন্ধানের জন্য প্রতিটি উপাদানকে কল করতে হবে, বা NSDictionaryবিপরীত চেহারা মানচিত্র বজায় রাখতে ম্যাপিং ডেটা টাইপ ব্যবহার করতে হবে।
অ্যাডাম রোজেনফিল্ড

1
ম্যাক্স ও এর কৌশলটি FormatType_toStringঅ্যারেতে এন্ট্রি যুক্ত করতে ভুলে যাওয়া সম্পর্কে ভাল ।
AechoLiu

50

আমার সমাধান:

সম্পাদন করা: আমি শেষে এমনকি একটি ভাল সমাধান জুড়েছেন, আধুনিক OBJ-সি ব্যবহার

1.
একটি অ্যারের মধ্যে কী হিসেবে রাখুন নাম থাকবে না।
নিশ্চিত করুন যে সূচীগুলি যথাযথ এনামগুলি এবং সঠিক ক্রমে (অন্যথায় ব্যতিক্রম)।
দ্রষ্টব্য: নামগুলি এমন একটি সম্পত্তি যা * _নম * হিসাবে সংশ্লেষিত হয়;

সংকলনের জন্য কোডটি পরীক্ষা করা হয়নি, তবে আমি আমার অ্যাপটিতে একই কৌশলটি ব্যবহার করেছি।

typedef enum {
  JSON,
  XML,
  Atom,
  RSS
} FormatType;

+ (NSArray *)names
{
    static NSMutableArray * _names = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _names = [NSMutableArray arrayWithCapacity:4];
        [_names insertObject:@"JSON" atIndex:JSON];
        [_names insertObject:@"XML" atIndex:XML];
        [_names insertObject:@"Atom" atIndex:Atom];
        [_names insertObject:@"RSS" atIndex:RSS];
    });

    return _names;
}

+ (NSString *)nameForType:(FormatType)type
{
    return [[self names] objectAtIndex:type];
}


//

2.
মডার্ন ওবজে-সি ব্যবহার করে আমরা এনামের কীগুলিতে বর্ণনাগুলি বাঁধতে একটি অভিধান ব্যবহার করতে পারি।
অর্ডার কিছু যায় আসে না

typedef NS_ENUM(NSUInteger, UserType) {
    UserTypeParent = 0,
    UserTypeStudent = 1,
    UserTypeTutor = 2,
    UserTypeUnknown = NSUIntegerMax
};  

@property (nonatomic) UserType type;

+ (NSDictionary *)typeDisplayNames
{
    return @{@(UserTypeParent) : @"Parent",
             @(UserTypeStudent) : @"Student",
             @(UserTypeTutor) : @"Tutor",
             @(UserTypeUnknown) : @"Unknown"};
}

- (NSString *)typeDisplayName
{
    return [[self class] typeDisplayNames][@(self.type)];
}


ব্যবহার (একটি শ্রেণীর উদাহরণ পদ্ধতিতে):

NSLog(@"%@", [self typeDisplayName]);



12
সচেতন থাকবেন যে যতবার আপনি কল করবেন +[typeDisplayNames], আপনি অভিধানটি পুনরায় তৈরি করছেন। এটি কেবলমাত্র কয়েকবার বলা হলেও এটি সূক্ষ্ম, তবে এটি যদি বহুবার বলা হয় তবে এটি খুব ব্যয়বহুল হবে। অভিধানটিকে একটি সিঙ্গলটন বানাতে আরও ভাল সমাধান হতে পারে, সুতরাং এটি কেবল একবার তৈরি হয়েছিল এবং অন্যথায় স্মৃতিতে থাকে। ক্লাসিক মেমরি বনাম সিপিইউ কনড্রাম।
জোয়েল ফিশার

বা এটিকে একটি স্ট্যাটিক ভেরিয়েবল হিসাবে পরিবর্তন করুন, উদাহরণস্বরূপ static NSDictionary *dict = nil; if(!dict) dict = @{@(UserTypeParent): @"Parent"}; return dict;মন্তব্যগুলি আপনাকে লাইন ব্রেক করতে দেয় না, এর জন্য দুঃখিত।
নটনাভরা

29

@ অ্যাডামরোসেনফিল্ডের উত্তর, @ ক্রিসটফ মন্তব্য এবং সরল সি এনামগুলিকে পরিচালনা করার জন্য অন্য কৌশলটি একত্রিত করার পরামর্শ দিচ্ছি:

// In a header file
typedef enum {
  JSON = 0,         // explicitly indicate starting index
  XML,
  Atom,
  RSS,

  FormatTypeCount,  // keep track of the enum size automatically
} FormatType;
extern NSString *const FormatTypeName[FormatTypeCount];


// In a source file
NSString *const FormatTypeName[FormatTypeCount] = {
  [JSON] = @"JSON",
  [XML] = @"XML",
  [Atom] = @"Atom",
  [RSS] = @"RSS",
};


// Usage
NSLog(@"%@", FormatTypeName[XML]);

সবচেয়ে খারাপ ক্ষেত্রে - যেমন আপনি যদি এনাম পরিবর্তন করেন তবে নাম অ্যারে পরিবর্তন করতে ভুলে যান - এটি এই কীটির জন্য শূন্য হয়ে যাবে।


12

ক্লাস শিরোনামে টাইপয়েড এনাম সংজ্ঞা দিন:

typedef enum {
    IngredientType_text  = 0,
    IngredientType_audio = 1,
    IngredientType_video = 2,
    IngredientType_image = 3
} IngredientType;

ক্লাসে এই জাতীয় পদ্ধতি লিখুন:

+ (NSString*)typeStringForType:(IngredientType)_type {
   NSString *key = [NSString stringWithFormat:@"IngredientType_%i", _type];
   return NSLocalizedString(key, nil);
}

লোকালাইজেবল.স্ট্রিং ফাইলের মধ্যে স্ট্রিং রয়েছে :

/* IngredientType_text */
"IngredientType_0" = "Text";
/* IngredientType_audio */
"IngredientType_1" = "Audio";
/* IngredientType_video */
"IngredientType_2" = "Video";
/* IngredientType_image */
"IngredientType_3" = "Image";

11

আমি কম্পাইলারের # স্ট্রিং টোকেনটি ব্যবহার করব (ম্যাক্রো সহ এটি আরও কমপ্যাক্ট তৈরি করতে):

#define ENUM_START              \
            NSString* ret;      \
            switch(value) {

#define ENUM_CASE(evalue)       \
            case evalue:        \
                ret = @#evalue; \
                break;

#define ENUM_END                \
            }                   \
            return ret;

NSString*
_CvtCBCentralManagerStateToString(CBCentralManagerState value)
{
    ENUM_START
        ENUM_CASE(CBCentralManagerStateUnknown)
        ENUM_CASE(CBCentralManagerStateResetting)
        ENUM_CASE(CBCentralManagerStateUnsupported)
        ENUM_CASE(CBCentralManagerStateUnauthorized)
        ENUM_CASE(CBCentralManagerStatePoweredOff)
        ENUM_CASE(CBCentralManagerStatePoweredOn)
    ENUM_END
}

এটি সি 99 এ দুর্দান্ত কাজ করেছে - আমি সি তে নতুন এবং আমি জিজ্ঞাসা করা প্রশ্নটি সম্পাদন করার সবচেয়ে পরিষ্কার উপায় বলে মনে করি। আমি সংজ্ঞায়িত নাও হতে পারে এমন আইটেমগুলির জন্য আমার প্রয়োগের ক্ষেত্রে একটি ডিফল্ট হিসাবে যুক্ত করেছি। খুব পরিষ্কার পদ্ধতি। ফলাফলের জন্য ধন্যবাদ। ম্যাক্রোর খুব কৌতূহলপূর্ণ ব্যবহার।
ট্র্যাভিসবিহীন

8

আমি এটি করার #defineপদ্ধতি পছন্দ করি :

// এটিকে আপনার .h ফাইলে @ ইন্টারফেস ব্লকের বাইরে রাখুন

typedef enum {
    JPG,
    PNG,
    GIF,
    PVR
} kImageType;
#define kImageTypeArray @"JPEG", @"PNG", @"GIF", @"PowerVR", nil

// Place this in the .m file, inside the @implementation block
// A method to convert an enum to string
-(NSString*) imageTypeEnumToString:(kImageType)enumVal
{
    NSArray *imageTypeArray = [[NSArray alloc] initWithObjects:kImageTypeArray];
    return [imageTypeArray objectAtIndex:enumVal];
}

উত্স (উত্স আর উপলব্ধ নেই)


@ দাইজ-দজন nilযদি ফিরে আসে তবে array.count <= enumValueকী হবে ?
anneblue

@ এ্যানব্লু যা ত্রুটিটি ধরবে .. এটি ভঙ্গুর হয়ে উঠবে কারণ আপনি যদি এনাম মান বা এনাম মান পরিবর্তনের পূর্ণসংখ্যার মান যুক্ত করেন তবে এটি ভুল হয়ে যায়। গৃহীত উত্তরটি ভাল হবে
দাইজ-দাজন

@ কোডারকেট :( দুঃখিত - নিশ্চিত হননি যে সেই ওয়েবসাইটটি কী হয়েছে। ব্যাক
ফিতে

উপরের উত্তর সম্পর্কে আমার একটি ছোট প্রশ্ন আছে। স্ট্রিং এলিমেন্টকে কীজমেট টাইপে রূপান্তর করা যায়। স্ট্রিং পেরিয়ে আমাকে ইমেজ টাইপএইনমটোস্ট্রিং পদ্ধতিটি কল করতে হবে you আপনি আমার সমস্যার জন্য আমাকে সাহায্য করতে পারেন।
গণেশ

1
আমি এই উত্তরটি সবচেয়ে ভাল পছন্দ করি কারণ আপনার এনামগুলির ঠিক পাশের স্ট্রিং সংজ্ঞা রয়েছে। একটি মান মিস করার কমপক্ষে সুযোগ। এবং @ গণেশ, কাঁচা মান থেকে রূপান্তর করতে, এটি করতে পারে: রিটার্ন (কেআইমেজটাইপ) [চিত্রপ্রকার টাইপআরাই সূচকঅফজেক্ট: কাঁচাভ্যালু];
হারিস

8

আমার তৈরি করতে এই পৃষ্ঠায় পাওয়া সমস্ত সমাধানগুলির এক ধরণের মিশ্রণ তৈরি করেছি, এটি এক ধরণের অবজেক্ট অরিয়েন্টেড এনুম এক্সটেনশন বা অন্য কোনও বিষয়।

আসলে আপনার যদি কেবল ধ্রুবকগুলির চেয়ে বেশি (যেমন পূর্ণসংখ্যার) প্রয়োজন হয় তবে আপনার সম্ভবত একটি মডেল অবজেক্টের প্রয়োজন হবে (আমরা সবাই এমভিসি সম্পর্কে কথা বলছি, তাই না?)

এটি ব্যবহার করার আগে নিজেকে কেবল প্রশ্নটি জিজ্ঞাসা করুন, আমি কি ঠিক আছি, আপনি কি সত্যিকারের কোনও মডেল অবজেক্টের দরকার নেই, যা ওয়েবসার্ভিস, প্লিস্ট, এসকিউএলাইট ডাটাবেস বা কোরডাটা থেকে শুরু করা হয়েছে?

যাইহোক এখানে কোড আসে (এমপিআই হ'ল "আমার প্রকল্পের সূচনা" এর জন্য, প্রত্যেকে এটি বা তাদের নাম ব্যবহার করে, মনে হয়):

MyWonderfulType.h :

typedef NS_ENUM(NSUInteger, MPIMyWonderfulType) {
    MPIMyWonderfulTypeOne = 1,
    MPIMyWonderfulTypeTwo = 2,
    MPIMyWonderfulTypeGreen = 3,
    MPIMyWonderfulTypeYellow = 4,
    MPIMyWonderfulTypePumpkin = 5
};

#import <Foundation/Foundation.h>

@interface MyWonderfulType : NSObject

+ (NSString *)displayNameForWonderfulType:(MPIMyWonderfulType)wonderfulType;
+ (NSString *)urlForWonderfulType:(MPIMyWonderfulType)wonderfulType;

@end

এবং MyWonderfulType.m:

#import "MyWonderfulType.h"

@implementation MyWonderfulType

+ (NSDictionary *)myWonderfulTypeTitles
{
    return @{
             @(MPIMyWonderfulTypeOne) : @"One",
             @(MPIMyWonderfulTypeTwo) : @"Two",
             @(MPIMyWonderfulTypeGreen) : @"Green",
             @(MPIMyWonderfulTypeYellow) : @"Yellow",
             @(MPIMyWonderfulTypePumpkin) : @"Pumpkin"
             };
}

+ (NSDictionary *)myWonderfulTypeURLs
{
    return @{
             @(MPIMyWonderfulTypeOne) : @"http://www.theone.com",
             @(MPIMyWonderfulTypeTwo) : @"http://www.thetwo.com",
             @(MPIMyWonderfulTypeGreen) : @"http://www.thegreen.com",
             @(MPIMyWonderfulTypeYellow) : @"http://www.theyellow.com",
             @(MPIMyWonderfulTypePumpkin) : @"http://www.thepumpkin.com"
             };
}

+ (NSString *)displayNameForWonderfulType:(MPIMyWonderfulType)wonderfulType {
    return [MPIMyWonderfulType myWonderfulTypeTitles][@(wonderfulType)];
}

+ (NSString *)urlForWonderfulType:(MPIMyWonderfulType)wonderfulType {
    return [MPIMyWonderfulType myWonderfulTypeURLs][@(wonderfulType)];
}


@end

দেখতে দুর্দান্ত লাগছে, তবে যখন আপনার কেবলমাত্র এর একটি মান প্রয়োজন হয় আপনি পুরো অভিধানটি বরাদ্দ এবং ফিরে আসছেন। দক্ষতা ভিএস সুন্দর কোড? আপনি যা চান তার উপর নির্ভর করে এবং আপনি যদি আপনার কোডটিতে বিশাল লুপের মতো এগুলি ব্যবহার না করেন তবে আপনি এটির সাথে ভাল হয়ে যাবেন। তবে এটি সম্ভবত "ডায়নামিক" বা কোনও হার্ড-কোডিং
এনামগুলির সাথে

5

আরেকটি সমাধান:

typedef enum BollettinoMavRavTypes {
    AMZCartServiceOperationCreate,
    AMZCartServiceOperationAdd,
    AMZCartServiceOperationGet,
    AMZCartServiceOperationModify
} AMZCartServiceOperation;

#define AMZCartServiceOperationValue(operation) [[[NSArray alloc] initWithObjects: @"CartCreate", @"CartAdd", @"CartGet", @"CartModify", nil] objectAtIndex: operation];

আপনার পদ্ধতিতে আপনি ব্যবহার করতে পারেন:

NSString *operationCheck = AMZCartServiceOperationValue(operation);

4

স্ট্রিং নির্ভরতা বাদ দিয়ে @ yar1vn উত্তর উন্নত করা হয়েছে:

#define VariableName(arg) (@""#arg)

typedef NS_ENUM(NSUInteger, UserType) {
    UserTypeParent = 0,
    UserTypeStudent = 1,
    UserTypeTutor = 2,
    UserTypeUnknown = NSUIntegerMax
};  

@property (nonatomic) UserType type;

+ (NSDictionary *)typeDisplayNames
{
    return @{@(UserTypeParent) : VariableName(UserTypeParent),
             @(UserTypeStudent) : VariableName(UserTypeStudent),
             @(UserTypeTutor) : VariableName(UserTypeTutor),
             @(UserTypeUnknown) : VariableName(UserTypeUnknown)};
}

- (NSString *)typeDisplayName
{
    return [[self class] typeDisplayNames][@(self.type)];
}

সুতরাং আপনি যখন এনাম এন্ট্রি নাম পরিবর্তন করবেন তখন সংশ্লিষ্ট স্ট্রিং পরিবর্তন হবে। আপনি যদি এই স্ট্রিংটি ব্যবহারকারীর কাছে না দেখান তবে কার্যকর।


আপনি কী ব্যাখ্যা করতে পারবেন "- ভেরিয়েবল নাম (আরগ) (@" "# আরগ) সংজ্ঞা দিন --- এবং সম্ভবত আরও ভাল সমাধান দিতে পারেন?
xyS ভার্মা

# সংজ্ঞা সহ, আপনি # বিকল্প পরিবর্তনের জন্য যখন # ব্যবহার করেন তখন যুক্তিটি স্বয়ংক্রিয়ভাবে ডাবল উদ্ধৃতিতে আবৃত হয়। সিতে, যখন দুটি স্ট্রিং একে অপরের পাশে কোডের মতো প্রদর্শিত হয় "foo""bar", "foobar"সংকলিত হয়ে গেলে স্ট্রিংয়ের ফলাফল হয় । সুতরাং, #define VariableName(arg) (@""#arg)হতে প্রসারিত VariableName(MyEnum)হবে (@"""MyEnum")। এর ফলে স্ট্রিং আসবে @"MyEnum"
ক্রিস ডগলাস

3

এনাম সংজ্ঞা দেওয়া যেমন:

typedef NS_ENUM(NSInteger, AssetIdentifier) {
    Isabella,
    William,
    Olivia
};

নীচে দেখানো হিসাবে আমরা একটি এনাম মানটিকে তার সম্পর্কিত স্ট্রিংয়ে রূপান্তর করতে ম্যাক্রো সংজ্ঞায়িত করতে পারি।

#define AssetIdentifier(asset) \
^(AssetIdentifier identifier) { \
switch (identifier) { \
case asset: \
default: \
return @#asset; \
} \
}(asset)

switchবিবৃতি ব্লক ব্যবহার করা টাইপ পরীক্ষা করা হয়, এবং এছাড়াও Xcode মধ্যে স্বয়ং-সম্পূর্ণ সমর্থন পেতে।

এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন


2

আমার কাছে একটি বড় অঙ্কের টাইপ ছিল যা আমি এটিকে দেখার জন্য রূপান্তর করতে চেয়েছিলাম NSDictionary। আমি sedওএসএক্স টার্মিনাল থেকে এই হিসাবে ব্যবহার করে শেষ করেছি :

$ sed -E 's/^[[:space:]]{1,}([[:alnum:]]{1,}).*$/  @(\1) : @"\1",/g' ObservationType.h

যা এই হিসাবে পড়তে পারে: 'লাইন এবং আউটপুটটিতে প্রথম শব্দটি ক্যাপচার করুন @ (শব্দ): @ "শব্দ",'

এই রেজেক্সটি 'অবজারভেশন টাইপ। H' নামে একটি শিরোনাম ফাইলটিতে এনামকে রূপান্তর করে যা এতে রয়েছে:

typedef enum : int { 
    ObservationTypePulse = 1,
    ObservationTypeRespRate = 2,
    ObservationTypeTemperature = 3,
    .
    .
}

যেমন কিছু মধ্যে:

    @(ObservationTypePulse) : @"ObservationTypePulse",
    @(ObservationTypeRespRate) : @"ObservationTypeRespRate",
    @(ObservationTypeTemperature) : @"ObservationTypeTemperature",
    .
    .

এরপরে @{ }একটি NSDictionaryঅনুসন্ধান তৈরি করতে আধুনিক উদ্দেশ্য-সি সিনট্যাক্স (উপরে @ yar1vn দ্বারা ব্যাখ্যা করা) ব্যবহার করে কোনও পদ্ধতিতে আবৃত করা যেতে পারে :

-(NSDictionary *)observationDictionary
{
    static NSDictionary *observationDictionary;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        observationDictionary = [[NSDictionary alloc] initWithDictionary:@{
                                 @(ObservationTypePulse) : @"ObservationTypePulse",
                                 @(ObservationTypeRespRate) : @"ObservationTypeRespRate",
                                 .
                                 .
                                 }];
    });
    return observationDictionary;
}

dispatch_onceবয়লার-প্লেট মাত্র নিশ্চিত করার যে স্ট্যাটিক পরিবর্তনশীল একটি থ্রেড-নিরাপদ পদ্ধতিতে ইনিশিয়ালাইজ করা হয়।

দ্রষ্টব্য: আমি ওএসএক্স-তে সিড রেজেক্স এক্সপ্রেশনটি দেখতে পেয়েছি বিজোড় - যখন আমি +'এক বা একাধিক'র সাথে মেলে ব্যবহার করার চেষ্টা করেছি তখন এটি কার্যকর হয়নি এবং {1,}প্রতিস্থাপন হিসাবে ব্যবহার করতে অবলম্বন করতে হয়েছিল


2

ব্যারি ওয়াকের উত্তরে আমি একটি প্রকরণ ব্যবহার করি, যা গুরুত্ব অনুসারে:

  1. অনুপস্থিত কেস ক্লজগুলি পরীক্ষা করার জন্য সংকলককে মঞ্জুরি দেয় (এটি যদি আপনার ডিফল্ট ধারা থাকে না তবে)।
  2. একটি অবজেক্টিভ-সি টিপিক্যাল নাম ব্যবহার করুন (জাভা নামের পরিবর্তে)।
  3. একটি নির্দিষ্ট ব্যতিক্রম উত্থাপন।
  4. খাটো হয়।

উদাহরণ:

- (NSString*)describeFormatType:(FormatType)formatType {    
    switch(formatType) {
        case JSON:
            return @"JSON";
        case XML:
            return @"XML";
        case Atom:
            return @"Atom";
        case RSS:
            return @"RSS";
    }
    [NSException raise:NSInvalidArgumentException format:@"The given format type number, %ld, is not known.", formatType];
    return nil; // Keep the compiler happy - does not understand above line never returns!
}

2

@ পিক্সেল এখানে সবচেয়ে উজ্জ্বল উত্তর যুক্ত করেছে: https://stackoverflow.com/a/24255387/1364257 দয়া করে, তাকে উত্সাহ দিন!

তিনি 1960 এর দশক থেকে ঝরঝরে এক্স ম্যাক্রো ব্যবহার করেন। (আমি আধুনিক ওজেজির জন্য তার কোডটি কিছুটা পরিবর্তন করেছি)

#define X(a, b, c) a b,
enum ZZObjectType {
    XXOBJECTTYPE_TABLE
};
typedef NSUInteger TPObjectType;
#undef X

#define XXOBJECTTYPE_TABLE \
X(ZZObjectTypeZero, = 0, @"ZZObjectTypeZero") \
X(ZZObjectTypeOne, , @"ZZObjectTypeOne") \
X(ZZObjectTypeTwo, , @"ZZObjectTypeTwo") \
X(ZZObjectTypeThree, , @"ZZObjectTypeThree")

+ (NSString*)nameForObjectType:(ZZObjectType)objectType {
#define X(a, b, c) @(a):c, 
    NSDictionary *dict = @{XXOBJECTTYPE_TABLE};
#undef X
    return dict[objectType];
}

এটাই. পরিষ্কার এবং ঝরঝরে। @ পিক্সেলকে ধন্যবাদ! https://stackoverflow.com/users/21804/pixel


@ আলেকজান্দ্রিজ আপনার সমাধান সরবরাহ করে, ম্যান। কারও কাছে কার্প করা সহজ। এই সমাধানটির সুস্পষ্ট উপকারিতা এবং সুস্পষ্ট বিপর্যয় উভয়ই রয়েছে। আপনার সমাধান দিয়ে বিশ্বকে আরও উন্নত করুন।
ভোইগার

2

আমি এখানে বেশ কয়েকটি পদ্ধতির সমন্বয় করেছি। আমি প্রিপ্রোসেসর এবং সূচকযুক্ত তালিকার ধারণাটি পছন্দ করি।

কোনও অতিরিক্ত গতিশীল বরাদ্দ নেই, এবং ইনলাইনিংয়ের কারণে সংকলকটি লুকিংটিকে অনুকূলিত করতে সক্ষম হতে পারে।

typedef NS_ENUM(NSUInteger, FormatType) { FormatTypeJSON = 0, FormatTypeXML, FormatTypeAtom, FormatTypeRSS, FormatTypeCount };

NS_INLINE NSString *FormatTypeToString(FormatType t) {
  if (t >= FormatTypeCount)
    return nil;

#define FormatTypeMapping(value) [value] = @#value

  NSString *table[FormatTypeCount] = {FormatTypeMapping(FormatTypeJSON),
                                      FormatTypeMapping(FormatTypeXML),
                                      FormatTypeMapping(FormatTypeAtom),
                                      FormatTypeMapping(FormatTypeRSS)};

#undef FormatTypeMapping

  return table[t];
}

1

সবার আগে, ফরম্যাটটাইপ.জেএসএন এর সাথে: জেএসওএন ফর্ম্যাটটাইপের সদস্য নয়, এটি ধরণের সম্ভাব্য মান। ফর্ম্যাটটাইপ এমনকি কোনও যৌগিক ধরণের নয় - এটি একটি স্কেলার।

দ্বিতীয়ত, এটি করার একমাত্র উপায় হ'ল ম্যাপিং টেবিল তৈরি করা। উদ্দেশ্য-সি-তে এটি করার সবচেয়ে সাধারণ উপায় হ'ল আপনার "চিহ্নগুলি" উল্লেখ করে এক ধরণের ধ্রুবক তৈরি করা, যাতে আপনার আরও NSString *FormatTypeJSON = @"JSON"কিছু ছিল।


1

নিম্নলিখিতটি এমন একটি সমাধান সরবরাহ করে যাতে নতুন এনাম যুক্ত করতে কেবল একটি লাইন সম্পাদনা প্রয়োজন, এনাম}} তালিকায় একটি লাইন যুক্ত করার অনুরূপ কাজ।

//------------------------------------------------------------------------------
// enum to string example
#define FOR_EACH_GENDER(tbd) \
        tbd(GENDER_MALE) \
        tbd(GENDER_FEMALE) \
        tbd(GENDER_INTERSEX) \

#define ONE_GENDER_ENUM(name) name,
enum
{
    FOR_EACH_GENDER(ONE_GENDER_ENUM)
    MAX_GENDER
};

#define ONE_GENDER(name) #name,
static const char *enumGENDER_TO_STRING[] = 
{
    FOR_EACH_GENDER(ONE_GENDER)
};

// access string name with enumGENDER_TO_STRING[value]
// or, to be safe converting from a untrustworthy caller
static const char *enumGenderToString(unsigned int value)
{
    if (value < MAX_GENDER)
    {
        return enumGENDER_TO_STRING[value];
    }
    return NULL;
}

static void printAllGenders(void)
{
    for (int ii = 0;  ii < MAX_GENDER;  ii++)
    {
        printf("%d) gender %s\n", ii, enumGENDER_TO_STRING[ii]);
    }
}

//------------------------------------------------------------------------------
// you can assign an arbitrary value and/or information to each enum,
#define FOR_EACH_PERSON(tbd) \
        tbd(2, PERSON_FRED,     "Fred",     "Weasley", GENDER_MALE,   12) \
        tbd(4, PERSON_GEORGE,   "George",   "Weasley", GENDER_MALE,   12) \
        tbd(6, PERSON_HARRY,    "Harry",    "Potter",  GENDER_MALE,   10) \
        tbd(8, PERSON_HERMIONE, "Hermione", "Granger", GENDER_FEMALE, 10) \

#define ONE_PERSON_ENUM(value, ename, first, last, gender, age) ename = value,
enum
{
    FOR_EACH_PERSON(ONE_PERSON_ENUM)
};

typedef struct PersonInfoRec
{
    int value;
    const char *ename;
    const char *first;
    const char *last;
    int gender;
    int age;
} PersonInfo;

#define ONE_PERSON_INFO(value, ename, first, last, gender, age) \
                     { ename, #ename, first, last, gender, age },
static const PersonInfo personInfo[] = 
{
    FOR_EACH_PERSON(ONE_PERSON_INFO)
    { 0, NULL, NULL, NULL, 0, 0 }
};
// note: if the enum values are not sequential, you need another way to lookup
// the information besides personInfo[ENUM_NAME]

static void printAllPersons(void)
{
    for (int ii = 0;  ;  ii++)
    {
        const PersonInfo *pPI = &personInfo[ii];
        if (!pPI->ename)
        {
            break;
        }
        printf("%d) enum %-15s  %8s %-8s %13s %2d\n",
            pPI->value, pPI->ename, pPI->first, pPI->last,
            enumGenderToString(pPI->gender), pPI->age);
    }
}

এই কৌশলটি এক্স-ম্যাক্রো নামে পরিচিত, যদি কেউ এটি সম্পর্কে পড়তে চায়। এটি এ থেকে আসে যে, traditionতিহ্যগতভাবে, ফর_ইচ_জেেন্ডার () ম্যাক্রোকে সর্বদা কেবল এক্স () বলা হত। আপনি যা করতে চাইতে পারেন তা হল একটি নতুন অর্থ দিয়ে এটি পুনরায় সংজ্ঞায়নের আগে # অপরিশোধিত FOR_Each_GENDER END
uliwitness

1

এখানে প্রতিটি উত্তরই মূলত একই কথা বলে, একটি নিয়মিত এনাম তৈরি করে তারপরে স্ট্রিংয়ের মধ্যে স্যুইচ করার জন্য একটি কাস্টম গেটর ব্যবহার করুন।

আমি ম্যাক্রোস ব্যবহার করে দ্রুত, সংক্ষিপ্ত এবং ক্লিনার - এমন একটি আরও সহজ সমাধান নিয়োগ করি!


#define kNames_allNames ((NSArray <NSString *> *)@[@"Alice", @"Bob", @"Eve"])
#define kNames_alice ((NSString *)kNames_allNames[0])
#define kNames_bob ((NSString *)kNames_allNames[1])
#define kNames_eve ((NSString *)kNames_allNames[2])

তারপরে আপনি কেবল টাইপ করা শুরু করতে পারেন kNam...এবং স্বয়ংক্রিয়রূপে আপনার পছন্দের তালিকা প্রদর্শন করা হবে!

অতিরিক্তভাবে, আপনি যদি একবারে সমস্ত নামের জন্য যুক্তি পরিচালনা করতে চান তবে আপনি কেবলমাত্র আক্ষরিক অ্যারেটি দ্রুত সাজানোর জন্য নিম্নরূপ:

for (NSString *kName in kNames_allNames) {}

শেষ অবধি, ম্যাক্রোগুলিতে এনএসএসস্ট্রিং ingালাই টাইপেইফের মতো আচরণের নিশ্চয়তা দেয়!


উপভোগ করুন!


0

অনেক উত্তর সব মোটামুটি ভাল।

আপনি যদি জেনেরিকের পরে থাকেন তবে অবজেক্টিভ সি সমাধান যা কিছু ম্যাক্রো ব্যবহার করে ...

মূল বৈশিষ্ট্যটি হ'ল এটি এনএসএসস্ট্রিং ধ্রুবকগুলির একটি স্ট্যাটিক অ্যারেতে সূচি হিসাবে এনাম ব্যবহার করে। অ্যাপল এপিআইগুলিতে প্রচলিত এনএসএসস্ট্রিংফ্রমএক্সএক্সএক্স এক্স ফাংশনের স্যুটটির মতো করে তুলতে অ্যারে নিজেই একটি ফাংশনে আবৃত হয়।

আপনাকে #import "NSStringFromEnum.h"এখানে http://pastebin.com/u83RR3Vk পাওয়া দরকার

[সম্পাদনা] এখানেও #import "SW+Variadic.h"পাওয়া দরকার http://pastebin.com/UEqTzYLf

উদাহরণ 1: স্ট্রিং রূপান্তরকারীগুলির সাথে একটি সম্পূর্ণ নতুন এনাম টাইপডেফ সংজ্ঞায়িত করুন।

myfile.h এ


 #import "NSStringFromEnum.h"

 #define define_Dispatch_chain_cmd(enum)\
 enum(chain_done,=0)\
 enum(chain_entry)\
 enum(chain_bg)\
 enum(chain_mt)\
 enum(chain_alt)\
 enum(chain_for_c)\
 enum(chain_while)\
 enum(chain_continue_for)\
 enum(chain_continue_while)\
 enum(chain_break_for)\
 enum(chain_break_while)\
 enum(chain_previous)\
 enum(chain_if)\
 enum(chain_else)\


interface_NSString_Enum_DefinitionAndConverters(Dispatch_chain_cmd)

মাইফিল.এম এ:


 #import "myfile.h"

 implementation_NSString_Enum_Converters(Dispatch_chain_cmd)

ব্যবহার করা :

NSString *NSStringFromEnumDispatch_chain_cmd(enum Dispatch_chain_cmd value);

NSStringFromEnumDispatch_chain_cmd(chain_for_c) আয় @"chain_for_c"

  enum Dispatch_chain_cmd enumDispatch_chain_cmdFromNSString(NSString *value);

enumDispatch_chain_cmdFromNSString(@"chain_previous") আয় chain_previous

উদাহরণ 2: বিদ্যমান এনুমের জন্য রূপান্তর রুটিন সরবরাহ করুন সেটিংস স্ট্রিং ব্যবহার করে এবং ফাংশনে ব্যবহৃত টাইপনেমটির নামকরণও প্রদর্শন করে।

myfile.h এ


 #import "NSStringFromEnum.h"


 #define CAEdgeAntialiasingMask_SETTINGS_PARAMS CAEdgeAntialiasingMask,mask,EdgeMask,edgeMask

 interface_NSString_Enum_Converters(CAEdgeAntialiasingMask_SETTINGS_PARAMS)

মাইফিল.এম এ:


 // we can put this in the .m file as we are not defining a typedef, just the strings.
 #define define_CAEdgeAntialiasingMask(enum)\
 enum(kCALayerLeftEdge)\
 enum(kCALayerRightEdge)\
 enum(kCALayerBottomEdge)\
 enum(kCALayerTopEdge)



 implementation_NSString_Enum_Converters(CAEdgeAntialiasingMask_SETTINGS_PARAMS)

0

এখানে কাজ করা হচ্ছে -> https://github.com/ndpiparava/ObjcEnumString

//1st Approach
#define enumString(arg) (@""#arg)

//2nd Approach

+(NSString *)secondApproach_convertEnumToString:(StudentProgressReport)status {

    char *str = calloc(sizeof(kgood)+1, sizeof(char));
    int  goodsASInteger = NSSwapInt((unsigned int)kgood);
    memcpy(str, (const void*)&goodsASInteger, sizeof(goodsASInteger));
    NSLog(@"%s", str);
    NSString *enumString = [NSString stringWithUTF8String:str];
    free(str);

    return enumString;
}

//Third Approcah to enum to string
NSString *const kNitin = @"Nitin";
NSString *const kSara = @"Sara";


typedef NS_ENUM(NSUInteger, Name) {
    NameNitin,
    NameSara,
};

+ (NSString *)thirdApproach_convertEnumToString :(Name)weekday {

    __strong NSString **pointer = (NSString **)&kNitin;
    pointer +=weekday;
    return *pointer;
}

যেহেতু সদৃশ জবাব অনুমোদিত নয়, এখানে সম্পূর্ণ সমাধান github.com/ndpiparava/ObjcEnumString
নিতিন

-2

আপনার প্রয়োজনের উপর নির্ভর করে, আপনি বিকল্পটি সন্ধানের জন্য যে পদ্ধতিটি সন্ধান করছেন তা অনুকরণ করতে সংকলক নির্দেশিকা ব্যবহার করতে পারেন।

 #define JSON @"JSON"
 #define XML @"XML"
 #define Atom @"Atom"
 #define RSS @"RSS"

কেবলমাত্র সাধারণ সংকলক ত্রুটিগুলি মনে রাখবেন, (নিরাপদ টাইপ করবেন না, সরাসরি অনুলিপি-পেস্ট উত্স ফাইলটি আরও বড় করে তোলে)


8
আমি মনে করি না এটি কাজ করবে; যে কোন জায়গায় #defineদৃশ্যমান হয়, তাহলে আপনি প্রকৃত enum মান ব্যবহার করতে সক্ষম হবেন না (অর্থাত JSONদিয়ে প্রতিস্থাপিত হবে @"JSON"প্রাক প্রসেসর দ্বারা এবং একটি যাও বরাদ্দ কম্পাইলার ত্রুটি পরিণাম ডেকে আনবে FormatType
ব্যারি Wark
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.