When replacing a value at some index with a new value within an NSMutableArray, the old value is held in memory. The hack to fix is to initialize a new NSMutableArray before every loop.
Steps to Reproduce:
- (id) init{
self.overlays = [[NSMutableArray alloc] initWithCapacity: [self.anotherArray count]];
}
- (void) someOtherMethod{
for(int i = 0 ; i < self.anotherArray ; i++){
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, height)];
[view setBackgroundColor:[UIColor colorWithRed:0
green:0
blue:0
alpha:1]];
[view setAlpha: .2];
[self.overlays insertObject:view atIndex: i]
}
}
- (void) main{
for(int i = 0 ; i < 4 ; i++){
[myObject someOtherMethod];
}
}
insertObject:atIndex effectively causes a memory leak, because it does not release the old value in the array at that index.
I filed a bug report and Apple responded:
insertObject:atIndex: is behaving as defined. It is doing an insertion, not a replacement. If you want replacement, you should instead use -replaceObjectAtIndex:withObject:
How could the insertObject:atIndex: ever be of any benefit, as you always lose the reference to the old object at that index.
Is this simply to avoid fixing the issue as it meets old documentation definitions?
The two methods do different things. Imagine the following array:
If you insert an element at position
1, like so:The array becomes equal to
@[ @1, @4, @2, @3 ]. The new element is inserted without removing another element.If, instead, you replace the element at position
1, like so:You get
@[ @1, @4, @3 ]. The previous object at that location is removed.