[iOS] 錯誤代碼:Collection was mutated while being enumerated

這錯誤通常是NSArray遇到的問題,在無意識中於iterate時,對NSArray進行了編輯,比方說你可能做了這樣的事情:

for (id obj in array){
        if (/* some condition */) {
                [array removeObject:obj];
        }
}

由於你在iterate時刪除了array內的物件,所以會造成這樣的錯誤。如果你真的要對array進行編輯,你可以這樣作:

[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
        if (/* some condition */) {
                *stop = YES;
                if (*stop) {
                        [array removeObject:obj];
                }
        }
}];

三個參數我解釋一下:
  1. obj是array內的物件
  2. idx是obj的index
  3. stop是一個bool值,設定成YES時,enumerate會暫停,讓你進行編輯,需注意的是,你不用將它再設回NO,他是針對每一個obj而存在,處理完後就會繼續enumerate了。
當然還有比較熟悉的作法,就是你新設定一個arrayTemp,然後對它enumerate,操作在原來的array上:

NSArray *arrayTemp = [NSArray arrayWithArray:array];
for (id obj in arrayTemp){
        if (/* some condition */) {
                [array removeObject:obj];
        }
}

另一種導致這種錯誤的情況是,你在enumerate的array,當你在enumerate時,他剛好在別的地方被編輯。

比方說它來自於一個NSMutableArray,而這個NSMutableArray在你enumerate時,進行了編輯,也會導致這個情況,因此,用於enumerate的NSArray,最好自己要copy一份,也就是使用arrayWithArray:來做一份新的。

留言