如何在迭代过程中安全地从nsmutablearray中删除对象?

时间:2014-06-05 06:21:56

标签: objective-c nsmutablearray

我在循环中使用了一个nsmutablearray,并希望删除刚遍历过的对象(或赋值nil)。 但如果我这样做,我会收到错误<__NSArrayM: 0x8c3d3a0> was mutated while being enumerated.'。代码如下

- (TreeNode*)depthLimitedSearch:(TreeNode *)current costLimit:(int)currentCostBound {

NSMutableArray *children=[NSMutableArray arrayWithArray:[current expandNodeToChildren]];
for (TreeNode *s in children) {
    if (s.puzzleBox.isFinalPuzzleBox) {//checking for final puzzleBox
        return s;
    }
    /*exploredNodes++;
    if (exploredNodes %10000==0) {
        NSLog(@"explored nodes for this treshold-%d are %d",currentCostBound,exploredNodes);
    }*/

    int currentCost =[s.cost intValue]+[s.heuristicsCost intValue];

    if (currentCost <= currentCostBound) {
        //[s.puzzleBox displayPuzzleBox];

        TreeNode *solution = [self depthLimitedSearch:s costLimit:currentCostBound];
        if (solution!=nil){//&& (bestSolution ==nil|| [solution.cost intValue] < [bestSolution.cost intValue])) {
            bestSolution = solution;
            return bestSolution;
        }
    }else {
        if (currentCost < newLimit) {
            //NSLog(@"new limit %d", currentCost);
            newLimit = currentCost;
        }
    }
    // here I want to free memory used by current child in children
    [children removeObject:s]
}
children=nil;
return nil;
}

并且我评论了我想要释放孩子使用空间的地方。

2 个答案:

答案 0 :(得分:3)

如果要删除数组中的元素,则不应使用for ... in循环。相反,你应该使用普通的for循环并向后移动,以确保你不会跳过任何项目。

for (NSInteger i = items.count - 1; i >= 0; i--) {
    if (someCondition) {
        [items removeObjectAtIndex:i];
    }
}

答案 1 :(得分:1)

您可以在另一个数组中收集要删除的项目,然后在一次传递中将其删除:

NSMutableArray *toRemove = [NSMutableArray array];
for (id candidate in items) {
    if (something) {
        [toRemove addObject:candidate];
    }
}
[items removeObjectsInArray:toRemove];

比手动迭代索引更容易,这只是要求逐个错误。 但不确定这与你的早期回报有何关系。