【问题标题】:Remove items in a for loop without side effects?在没有副作用的情况下删除 for 循环中的项目?
【发布时间】:2011-08-15 03:25:21
【问题描述】:

我可以在没有副作用的情况下删除我在 Objective-C for 循环中循环的项目吗?

例如,这样可以吗?

for (id item in items) {
   if ( [item customCheck] ) {
      [items removeObject:item];   // Is this ok here?
}

【问题讨论】:

    标签: objective-c for-loop nsmutablearray nsarray fast-enumeration


    【解决方案1】:

    你可以这样删除:

        //Create array
        NSMutableArray* myArray = [[NSMutableArray alloc] init];
    
        //Add some elements
        for (int i = 0; i < 10; i++) {
            [myArray addObject:[NSString stringWithFormat:@"i = %i", i]];
        }
    
        //Remove some elements =}
        for (int i = (int)myArray.count - 1; i >= 0 ; i--) {
            if(YES){
                [myArray removeObjectAtIndex:i];
            }
        }
    

    【讨论】:

    • 我-- 与众不同。 ;)
    【解决方案2】:

    Nope:

    枚举是“安全的”——枚举器有一个突变保护,因此如果您尝试在枚举期间修改集合,则会引发异常。

    Using Enumerators 中提供了更改要枚举的数组的选项:复制数组并枚举,或者建立一个索引集,以便在循环后使用。

    【讨论】:

    • 谢谢 - McCygnus 的建议似乎坚持这一点,所以看起来没问题
    【解决方案3】:

    不,如果在快速枚举 for 循环中对数组进行变异,则会出现错误。制作数组的副本,对其进行迭代,然后从原始数组中删除。

    NSArray *itemsCopy = [items copy];
    
    for (id item in itemsCopy) {
       if ( [item customCheck] )
          [items removeObject:item];   // Is this ok here
    }
    
    [itemsCopy release];
    

    【讨论】:

    • 这不会跳过 1 个元素,因为当删除发生时每个数组元素都会移动 1。
    • 不,我们不会在本示例中使用索引从显示中删除项目。 NSMutableArray 的 removeObject: 方法查看数组并删除它找到的对象的第一个引用。在内部调用使用 indexOfObject: 和 removeObjectAtIndex: 来执行此操作。如果您有足够大的阵列,这可能会影响性能。您可以通过跟踪索引对其进行一些优化,但随后您必须对其进行调整以进行删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    相关资源
    最近更新 更多