How to remove elements in NSMutableArray or NSMutableDictionary during enumeration?

前端 未结 3 418
梦毁少年i
梦毁少年i 2021-01-04 10:15

I am using block based enumeration similar to the following code:

[[[rows objectForKey:self.company.coaTypeCode] objectForKey:statementType] 
    enumerateOb         


        
3条回答
  •  情话喂你
    2021-01-04 10:34

    Whether you build up an index set during enumeration, or modify the array itself during enumeration, you will have to give up NSEnumerationConcurrent, because most Cocoa objects cannot safely be modified simultaneously from multiple threads.

    Anyway, the simplest (but maybe not most efficient) approach is to just enumerate a copy of the container.

    For an array, you can enumerate a copy in reverse. I assume that as each item is being enumerated, you may decide to remove that item, but not other items previously enumerated or yet to be enumerated.

    NSMutableArray *array = [[rows objectForKey:self.company.coaTypeCode] objectForKey:statementType];
    [[array copy] enumerateObjectsWithOptions: NSEnumerationReverse 
        usingBlock:^(id coaItem, NSUInteger idx, BOOL *stop) {
        if ([self objectIsTooUglyToExist:coaItem])
            [array removeObjectAtIndex:idx];
    }]
    

    You have to enumerate the array in reverse to avoid changing the not-yet-enumerated part of the array.

    For a dictionary, you can just enumerate a copy with no special options:

    NSMutableDictionary *dictionary = someDictionary;
    [[dictionary copy] enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if ([self object:obj isTooUglyToExistAtKey:key])
            [dictionary removeObjectForKey:key];
    }];
    

提交回复
热议问题