2014-06-05 4 views
0

루프에서 nsmutablearray를 사용 중이고 방금 통과 한 객체를 제거 (또는 nil 지정)하고 싶습니다. 하지만 그렇게한다면 <__NSArrayM: 0x8c3d3a0> was mutated while being enumerated.'이라는 오류가 발생합니다. 코드는 다음과 같습니다.nsmutablearray에서 객체를 반복하면서 안전하게 제거하는 방법은 무엇입니까?

- (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; 
} 

그리고 나는 아이가 사용하는 공간을 공개하고자하는 장소를 주석 처리했습니다.

+0

GO BACKWARDS - 오래된 프로그래밍 트릭. 더 완벽한 솔루션은 데이터베이스에서 어떻게 수행하는지입니다 .. please_delete_me라고 표시된 다른 열 (필드, 무엇이든)을 가지고 거기에서부터 진행하십시오. 쓰레드는 스레드, 데이터의 다른 소비자 등을 처리 할 때 광범위하게 의미가 복잡합니다. – Fattie

답변

3

배열의 요소를 제거하려면 for ... in 루프를 사용하면 안됩니다. 대신 일반 for 루프를 사용하고 항목을 건너 뛰지 않도록 뒤로 이동해야합니다.

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

0보다 크거나 같지 않은가? – Fattie

+0

다른 객체와 아무 것도하지 않기 때문에 항상 거기에있을 객체에 대해 항상 색인 x를 보유하므로 앞으로는 사용하지 않아야합니다. – Revinder

+0

@Joe : 예, 감사합니다. – Senseful

1

당신은 항목을 다른 배열에서 제거 할 수집하고 이후 단일 패스에서 그들을 제거 할 수 있습니다

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

그냥 오프에 의해 요구 손으로 인덱스, 반복보다 쉽게 한 번의 오류. 그러나 초기 반품과 관련하여 이것이 어떻게 수행되는지는 잘 모릅니다.

관련 문제