5

I am trying to implement a simple method, however I am still quite a newbie on objective-c.

I have this simple method which is trying to convert from an id to a specific value in enum, if matched.

This is the enum

typedef enum {
   DXTypeUnknown = 0,
   DXDatasource = 1,
   DXGroup = 2
} DXPropertyType;

And this is the relevant method:

-(DXPropertyType)typeFromObject:(id)_type {
    int _t = [_type intValue];

    switch (_t) {
        case DXDatasource:
            return [NSNumber numberWithInt:DXDatasource];
        case DXGroup:
            return [NSNumber numberWithInt:DXGroup];


        default:
            return [NSNumber numberWithInt:DXTypeUnknown];
    } 
}

The very first check I would to implement is if the id can be converted to an int, then see if it falls in the two relevant categories group or datasource, or return a default value if not. Could you tell me if the switch/case I implemented is a proper solution or not ? I would like also this method not to causing crash of an application, so what could be advisable to check, keeping in mind that in any case the default value is to be returned.

thanks

[EDIT] I forgot to say that this value is going to be stored in a field of a NSManagedObject, which by CoreData restriction can be an NSNumber, so probably there's a better solution instead of an enum.

Leonardo
  • 9,607
  • 17
  • 49
  • 89
  • What's `id`? Is it any random object or an instance of a specific class? – Deepak Danduprolu Jul 08 '11 at 13:19
  • For the moment is an object taken from a plist, and stored in a dictionary, and recall with [dict objectForKey], but I would like to extend this case and think about any random object. – Leonardo Jul 08 '11 at 13:23

3 Answers3

4

It might be a good idea to include this code to check if the id can be used:

if (![_type respondsToSelector:@selector(intValue)])
    return nil;

However, if you'll always pass a NSNumber go ahead and declare the method as:

- (DXPropertyType)typeFromObject:(NSNumber)_type;

In your code, you're returning a NSNumber. I don't think that's what you really want, as you'd be doing nothing with the NSNumber passed. Return the enum item:

-(DXPropertyType)typeFromObject:(id)_type {

    if (![_type respondsToSelector:@selector(intValue)])
        return nil;

    int _t = [_type intValue];

    switch (_t) {
        case DXDatasource:
            return DXDatasource;
        case DXGroup:
            return DXGroup;


        default:
            return DXTypeUnknown;
    } 
}

And then this can be simplified to:

- (DXPropertyType)typeFromObject:(id)_type {

    if ([_type respondsToSelector:@selector(intValue)]) {

        int t = [_type intValue];
        DXPropertyType property_t;

        if (t >= 1 && t <= 2)
            property_t = t;
        else
            property_t = DXTypeUnknown;

        return property_t;
    }
    return nil;
}
sidyll
  • 57,726
  • 14
  • 108
  • 151
  • Sorry @Leonardo, I didn't see you edited your question requesting that the returned value should be a NSNumber. – sidyll Jul 08 '11 at 13:34
  • uhm...I think most of the code can also be used in NSNumber returns, do you know if 'id' is responding to intValue does mean that it can always be converted to int ? In the worst scenario, could an id with value '1xy' respond to intValue ? – Leonardo Jul 08 '11 at 13:40
  • @Leonardo: an `id` means any kind of object. So you could pass an NSPipe to this method. It's not something that holds an integer, and it does not respond to the method `intValue` so nil is returned. Otherwise, calling `intValue` in an object that does not "accept" it will crash. If you declare your parameter as accepting only NSNumbers, as I said in the answer, it will work fine but leaving as `id` is better in some cases. For example, NSString also has a `intValue` method, so you could pass an NSString @"2" to your method and it would work. – sidyll Jul 08 '11 at 13:45
  • Hi @sidyll. I try to use this "if (![_type respondsToSelector:@selector(intValue)]) return nil;". But the compiler sais: Receiver type is not an Objective-C class. Maybe you can help me here: http://stackoverflow.com/questions/14853518/check-if-a-objective-c-enum-exists/14854084#14854084 – Luda Feb 13 '13 at 13:16
0

Your switch statement is a good solution and will not cause a crash.

However, your method returns a NSNumber when it expects a different return. I suggest changing the method to

-(NSNumber)typeFromObject:(id)_type
eazimmerman
  • 599
  • 4
  • 20
0

You specify that your method returns an enum, but you return objects. So either return the enum values or specify the return type to be NSNumber *.

A different solution could be using singleton objects instead of an enum, but that's probably more work than it's worth. Think [NSNull null].

DarkDust
  • 90,870
  • 19
  • 190
  • 224