數(shù)組遍歷自身的同時(shí)刪除元素

我們?cè)诒闅v可變數(shù)組時(shí),最好不要做刪除數(shù)組中元素的操作。

因?yàn)閯h除操作可能會(huì)引起數(shù)組容量的變化,導(dǎo)致數(shù)組越界等問(wèn)題。

以前在使用for循環(huán)遍歷的時(shí)候遇到過(guò)這個(gè)問(wèn)題。

當(dāng)時(shí)的做法是使用enumerateObjectsUsingBlock:,但是這次又遇到這個(gè)問(wèn)題時(shí),順便好好的測(cè)試了一下for、for in、enumerateObjectsUsingBlock:。

實(shí)驗(yàn)結(jié)果如下:

NSMutableArray*array = [NSMutableArrayarrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];[array enumerateObjectsUsingBlock:^(id_Nonnull obj, NSUInteger idx,BOOL* _Nonnull stop) {if([obj isEqualToString:@"3"]) {? ? ? ? [array removeObject:obj];? ? }}];NSLog(@"%@",array);// 輸出結(jié)果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

結(jié)果正常。

使用for in:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(NSString *objinarray) {if([obj isEqualToString:@"3"]) {? ? ? ? [arrayremoveObject:obj];? ? }}NSLog(@"%@",array);

1

2

3

4

5

6

7

1

2

3

4

5

6

7

結(jié)果出現(xiàn)崩潰,信息如下:

2016-11-1122:48:06.886Solutions[15297:2231002] *** Terminating app duetouncaughtexception'NSGenericException', reason:'*** Collection <__NSArrayM: 0x1001060b0> was mutated while being enumerated.'*** First throw call stack:(0CoreFoundation0x00007fff929c14f2__exceptionPreprocess +1781libobjc.A.dylib0x00007fff8fcb2f7eobjc_exception_throw +482CoreFoundation0x00007fff92a2815c__NSFastEnumerationMutationHandler +3003Solutions0x0000000100000d1cmain +5084libdyld.dylib0x00007fff90cd05adstart +1)libc++abi.dylib: terminatingwithuncaughtexceptionoftypeNSException

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10

使用for:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(inti =0; i

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

結(jié)果正常,可能是蘋果對(duì)普通的for循環(huán)內(nèi)部的處理做了修正,以前這樣寫(xiě)是會(huì)報(bào)錯(cuò)的。

其實(shí),最正確與穩(wěn)妥的方案,是對(duì)數(shù)組逆序遍歷,然后再刪除元素就沒(méi)有問(wèn)題了。

例如for in的逆序遍歷:

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(NSString *obj inarray.reverseObjectEnumerator) {if([obj isEqualToString:@"3"]) {? ? ? ? [arrayremoveObject:obj];? ? }}NSLog(@"%@",array);// 輸出結(jié)果:(1,2,4,5)

1

2

3

4

5

6

7

8

1

2

3

4

5

6

7

8

使用

NSMutableArray*array = [NSMutableArrayarrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id_Nonnull obj, NSUInteger idx,BOOL* _Nonnull stop) {if([obj isEqualToString:@"3"]) {? ? ? ? ? ? ? ? [array removeObject:obj];? ? ? ? ? ? }? ? ? ? }];NSLog(@"%@",array);// 輸出結(jié)果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

關(guān)于for 的逆序

NSMutableArray *array= [NSMutableArray arrayWithArray:@[@"1",@"2",@"3",@"4",@"5"]];for(inti =array.count -1; i >=0; i--) {? ? NSString *obj =array[i];if([obj isEqualToString:@"3"]) {? ? ? ? [arrayremoveObject:obj];? ? }}NSLog(@"%@",array);// 輸出結(jié)果:(1,2,4,5)

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

以前做Java開(kāi)發(fā)的時(shí)候,也遇到過(guò)這種遍歷刪除元素的,那時(shí)候的做法是在遍歷,刪除元素后做一次i–操作。

現(xiàn)在想來(lái),也可以逆序遍歷然后直接刪除即可。


====================================

或者樓主可以用 while 循環(huán)語(yǔ)句來(lái)做。

例如:

while(array.count>0)

{

obj = [array objectAtIndex:0];

//判斷處理

//remove

[array removeObjectAtIndex:0];

}

=========================================

可以用NSPredicate來(lái)完成:

NSArray *sourceArray = @[];

NSArray *whatYouNeedArray = [sourceArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

return ![evaluatedObject shouldBeDeleted];

}]];

whatYouNeedArray就是你要的array,已經(jīng)去除掉該刪除的項(xiàng)。

=======================================

一般不要這樣做,如果要?jiǎng)h除,一定要在刪除之后,break.

Oc語(yǔ)言中有三種遍歷數(shù)組的方式,一是傳統(tǒng)的for循環(huán),二是for-in循環(huán),三是迭代器。其中,第一種方式的效率最低。第二種遍歷方法如下,第三種使用比較少,你可以自己去網(wǎng)上看下。

for (NSString * str in names)

{

if ([str isEqualTo: @"something"]){

[names removeObject: str];

break;//一定要有break,否則會(huì)出錯(cuò)的。

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容