yoninja
yoninja

Reputation: 1962

What is a better way to check if string is a member of a const struct?

I want to check if a string is in a const struct. The way I do it is like this:

In my MyClass.h:

extern const struct MyAttributes {
    __unsafe_unretained NSString *attribute1;
    __unsafe_unretained NSString *attribute2;
    __unsafe_unretained NSString *attribute3;
    __unsafe_unretained NSString *attribute4;
    __unsafe_unretained NSString *attribute5;
} MyAttributes;

Then in my MyClass.m I have:

const struct MyAttributes MyAttributes = {
    .attribute1 = @"attribute1",
    .attribute2 = @"attribute2",
    .attribute3 = @"attribute3",
    .attribute4 = @"attribute4",
    .attribute5 = @"attribute5"
};

...

- (void)someMethod
{
    BOOL test1 = [self check:@"test"];
    BOOL test2 = [self check:@"attribute1"];
}

- (BOOL)check:(NSString *)string
{
    return [string isEqualToString:MyAttributes.attribute1] ||
        [string isEqualToString:MyAttributes.attribute2] ||
        [string isEqualToString:MyAttributes.attribute3] ||
        [string isEqualToString:MyAttributes.attribute4] ||
        [string isEqualToString:MyAttributes.attribute5];
}

Well, this works. But, is there a better way to implement - (void)check so that, if I update MyAttributes, I won't have to update - (void)check?

Upvotes: 0

Views: 141

Answers (2)

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 21966

You can convert it to an Objective-C array and then see if it contains the string you're looking for:

- (BOOL) check: (NSString*) string {
    // I renamed the variable MyAttributes to myAttributes, following naming conventions
    __unsafe_unretained id* ptr;
    struct MyAttributes* attrPtr= &myAttributes;
    memcpy(&ptr, &attrPtr, sizeof(id*));
    NSArray* array= [NSArray arrayWithObjects: ptr count: sizeof(MyAttributes)/sizeof(NSString*)];
    return [array containsObject: string];
}

The C-style way is to treat the struct as a C-array:

- (BOOL)check:(NSString *)string {
    BOOL result= NO;
    // I renamed the variable MyAttributes to myAttributes, following naming conventions
    NSString* __unsafe_unretained * strPtr;
    struct MyAttributes* ptr= &myAttributes;
    memcpy(&strPtr, &ptr, sizeof(NSString**));
    for(size_t i=0; i<sizeof(MyAttributes)/sizeof(NSString*) && !result;i++) {
        result= [string isEqualToString: strPtr[i] ];
    }
    return result;
}

PS: I used memcpy to avoid bridge-casting, since the strings are already retained in myAttributes.

Upvotes: 1

Injectios
Injectios

Reputation: 2797

you can dig in the direction of keeping struct items in NSArray

Possible answer:

Cocoa structs and NSMutableArray

then in - check method use containsObject: or array iteration to check if string is there.

Upvotes: 0

Related Questions