Method sends its own selector to self
ID |
objectivec.maintainability.direct_recursion |
Severity |
low |
Remediation Complexity |
hard |
Remediation Risk |
medium |
Remediation Effort |
high |
Resource |
Control Flow |
Language |
Objective-C |
Description
Reports a method whose body sends its own selector to self. The body is bounded by the method’s closing brace in the first column, so a call to a selector that another method happens to define is not reported, and neither is a call to a different receiver or to a selector whose name merely starts with this one’s. Indirect recursion through a second method is out of reach of a syntactic check and is not reported.
Rationale
Recursion moves the loop bound out of the code and into the shape of the data, so a structure that is deeper than expected - or that contains a cycle - exhausts the stack instead of looping too long, and a stack overflow gives no usable diagnostic. Objective-C message sends are also markedly more expensive per level than a loop iteration, so a recursive walk over a large structure costs both stack and time that an iterative one does not.
The following code illustrates the pattern detected by this rule:
@implementation TreeWalker
- (void)refresh {
[self prepare];
// FLAGGED: Method sends its own selector to self
[self refresh];
}
- (void)reload {
NSLog(@"reload");
}
- (void)stopTimer {
NSLog(@"stopped");
}
@end
Remediation
Where the recursion walks a structure, rewrite it as a loop over an explicit stack or queue, which puts the depth under your control and turns exhaustion into an ordinary error. Where it must stay recursive, make the base case unmistakable and bound the depth with a parameter that the method refuses to exceed.