NSInvocation arguments set without retainArguments

ID

objectivec.correctness.nsinvocation_arg_lifetime

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Resource Management

Language

Objective-C

Description

Reports a setArgument:atIndex: call on an NSInvocation in a method that never sends retainArguments, and that never invokes the invocation itself. The region is the method, bounded by its own closing brace, so a retainArguments in the method above or below does not count, and the order of the two calls within the method does not matter.

Rationale

NSInvocation copies the bytes of each argument but does not retain the objects they point at, so an invocation stored for later holds pointers whose owners may already be gone by the time it runs. The result is a use-after-free that depends on when the autorelease pool drains, so it survives testing and fails under memory pressure or on a background queue.

The following code illustrates the pattern detected by this rule:

@implementation Scheduler
- (void)scheduleUpdateWithName:(NSString *)name {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:self.signature];
    [invocation setTarget:self.worker];
    [invocation setSelector:@selector(applyName:)];
    // FLAGGED: NSInvocation arguments set without retainArguments
    [invocation setArgument:&name atIndex:2];
    self.pending = invocation;
}
@end

Remediation

Send retainArguments to the invocation once every argument has been set, before storing or scheduling it. Where the invocation is built and run in the same place, invoke it there instead of storing it, so the arguments cannot outlive the call.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved