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

Remediation

Write the container as a literal - @[first, second] and @{@"count": value}. Where a mutable container is needed, build the literal and copy it: [@[first, second] mutableCopy].

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved