hkatz
hkatz

Reputation: 961

Looking for a simpler Objective-C solution

Maybe simpler isn't the proper word; terse might do as well. I'm well-aware that Objective-C is a verbose language; I'm just wondering if it has to be as verbose as it is in the solution I'm showing below. I'm relatively new to the language.

This piece of code counts the number of each type of field in a record, pursuant to generating a variable-height UITableViewCell containing one label per field. My question isn't about how to do this -- I've already figured that out -- I'm just wondering: isn't there a simpler or less verbose way of doing this in Objective-C, using an NSDictionary object? Is this as terse as it gets using an NSDictionary? Solutions using other collection-type objects are also welcome.

Here's my -PartsRecord.countFields method. I've simplified the code slightly.

-(NSDictionary*) countFields {  
NSDictionary* dict = [[NSDictionary alloc] initWithObjectAndKeys:  
     @"s", [NSNumber numberWithUnsignedInt: [self.struts count]],  
     @"h", [NSNumber numberWithUnsignedInt: [self.headAssemblies count]],  
     @"l", (self.leftVent == nil) ?   [NSNumber numberWithUnsignedInt: 0] :  
                                      [NSNumber numberWithUnsignedInt: 1],  
     @"r", (self.rightVent == nil) ?  [NSNumber numberWithUnsignedInt: 0] :  
                                      [NSNumber numberWithUnsignedInt: 1],  
     nil ];  
return dict;  

}

Any errors in the above code are errors in transcription , not actual errors in the code.
TIA,
Howard

Upvotes: 2

Views: 1415

Answers (6)

epatel
epatel

Reputation: 46051

I think that using macros are quite ok to simplify typing and increase the readability

#define SET_KEY_NUMBER( _key, _value ) \
  [NSNumber numberWithUnsignedInt:_value], _key
#define SET_KEY_BOOL( _key, _bool ) \
  [NSNumber numberWithUnsignedInt: (_bool) ? 1 : 0], _key

-(NSDictionary*) countFields {  
    NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys: 
      SET_KEY_NUMBER( @"s", [self.struts count] ),
      SET_KEY_NUMBER( @"h", [self.headAssemblies count] ),
      SET_KEY_BOOL(   @"l", self.leftVent == nil ),
      SET_KEY_BOOL(   @"r", self. rightVent == nil ),
      nil ];  
    return dict;
}

...and @Matt Ball is correct, when returning a object it should be autoreleased

Upvotes: 0

dreamlax
dreamlax

Reputation: 95335

Does it have to be a dictionary? If not, perhaps resorting to some plain C might be easier to comprehend.

typedef struct {
    unsigned strutCount;
    unsigned headAssembliesCount;
    BOOL leftVent;
    BOOL rightVent;
} Fields;


- (void) countFields:(Fields *) fields
{
    fields->strutCount = [self.struts count];
    fields->headAssembliesCount = [self.headAssemblies count];
    fields->leftVent = (self.leftVent != nil);
    fields->rightVent = (self.rightVent != nil);
}

Upvotes: 1

Ashley Clark
Ashley Clark

Reputation: 8823

Unless you're intending to key on the numbers, your object ordering is wrong. It should be object then key.

dict = [NSDictionary dictionaryWithObjectsAndKeys:
   [NSNumber numberWithUnsignedInt: [self.struts count]], @"s",
   [NSNumber numberWithUnsignedInt: [self.headAssemblies count]], @"h",
   [NSNumber numberWithUnsignedInt: self.leftVent  ? 1 : 0], @"l", 
   [NSNumber numberWithUnsignedInt: self.rightVent ? 1 : 0], @"r",
   nil ];

This way, calling [dict objectForKey:@"s"] would return the [self.struts count] number object.

Upvotes: 3

user23743
user23743

Reputation:

-[NSNumber numberWithInt: 0] and -[NSNumber numberWithUnsignedInt: 0] are the same number (in fact, they may even be the same object on some implementations of Cocoa).

Upvotes: 0

Matt Ball
Matt Ball

Reputation: 6618

You could also change [[NSDictionary alloc] initWithObjectsAndKeys:] to [NSDictionary dictionaryWithObjectsAndKeys:].

This would be a good idea anyway, since your code is allocating an NSDictionary without releasing it. -dictionaryWithObjectsAndKeys: returns an autoreleased dictionary.

Upvotes: 2

cobbal
cobbal

Reputation: 70743

@"l", [NSNumber numberWithUnsignedInt: self.leftVent  ? 1 : 0],
@"r", [NSNumber numberWithUnsignedInt: self.rightVent ? 1 : 0],

will shorten it by 2 lines

Upvotes: 3

Related Questions