当使用NSMutableArray中的新值替换某个索引处的值时,旧值将保留在内存中。要解决的问题是在每个循环之前初始化一个新的NSMutableArray。
重现步骤:
- (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会有效地导致内存泄漏,因为它不会释放该索引处数组中的旧值。
我提交了一份错误报告,Apple回应道:
insertObject:atIndex:表现为已定义。它正在插入,而不是替代。如果要替换,则应使用-replaceObjectAtIndex:withObject:
insertObject:atIndex:怎么可能有任何好处,因为你总是丢失对该索引处旧对象的引用。
这是否只是为了避免修复问题,因为它符合旧的文档定义?
答案 0 :(得分:12)
这两种方法做了不同的事情。想象一下以下数组:
NSMutableArray *anArray = [@[ @1, @2, @3 ] mutableCopy];
如果在位置1
插入元素,请执行以下操作:
[anArray insertObject:@4 atIndex:1];
数组等于@[ @1, @4, @2, @3 ]
。插入新元素时不会删除其他元素。
相反,如果替换位置1
上的元素,请执行以下操作:
[anArray replaceObjectAtIndex:1 withObject:@4];
你得到@[ @1, @4, @3 ]
。删除该位置的上一个对象。
答案 1 :(得分:3)
insertObject:atIndex
不会删除旧项目。相反,它会在您指定的索引处插入新项。调用此方法后,数组的元素计数增加1.
这与replaceObjectAtIndex:withOjbect
不同,后者是替代品。数组的元素数保持不变。
插入就是这样做的。考虑一个包含5个元素的数组:如果你调用[myArray insertObject:insertedObj atIndex:1];
,myArray实例现在有6个元素,在第一个索引处插入了insertedObj
。