NSArray or NSDictionary factory call instead of a container literal
ID |
objectivec.maintainability.use_container_literal |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Idiom |
Language |
Objective-C |
Description
Reports a call to an NSArray or NSDictionary class factory that the container literal syntax @[…] or @{…} replaces. The mutable classes are not reported, because they have no literal form, and neither is arrayWithObjects:count:, which builds an array from a C buffer. Occurrences inside a comment or a string literal are not reported.
Rationale
The factory forms are terminated by a nil sentinel rather than by their own syntax, so a missing nil reads the caller’s stack until it happens to find one, and a nil value in the middle of the list silently truncates the container - a bug that shows up as a short array far from the call that built it. The literal forms have no sentinel, so neither mistake is expressible, and @{} puts each key next to its value instead of interleaving values and keys in one flat list.
The following code illustrates the pattern detected by this rule:
@implementation Containers
- (void)factories:(NSString *)name value:(NSNumber *)value {
// FLAGGED: NSArray or NSDictionary factory call instead of a container literal
NSArray *pair = [NSArray arrayWithObjects:name, @"second", nil];
// FLAGGED: NSArray or NSDictionary factory call instead of a container literal
NSArray *single = [NSArray arrayWithObject:name];
// FLAGGED: NSArray or NSDictionary factory call instead of a container literal
NSDictionary *map = [NSDictionary dictionaryWithObjectsAndKeys:value, @"count", name, @"name", nil];
// FLAGGED: NSArray or NSDictionary factory call instead of a container literal
NSDictionary *one = [NSDictionary dictionaryWithObject:value forKey:@"count"];
// FLAGGED: NSArray or NSDictionary factory call instead of a container literal
NSArray *nested = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], nil];
NSLog(@"%@ %@ %@ %@ %@", pair, single, map, one, nested);
}
@end