Reputation: 961
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
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
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
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
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
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
Reputation: 70743
@"l", [NSNumber numberWithUnsignedInt: self.leftVent ? 1 : 0],
@"r", [NSNumber numberWithUnsignedInt: self.rightVent ? 1 : 0],
will shorten it by 2 lines
Upvotes: 3