Ios 在NSMutableArray副本上使用快速枚举删除对象的详细信息

Ios 在NSMutableArray副本上使用快速枚举删除对象的详细信息,ios,objective-c,cocoa-touch,nsmutablearray,fast-enumeration,Ios,Objective C,Cocoa Touch,Nsmutablearray,Fast Enumeration,我学到了一个艰难的方法,即当您在NSMutableArray中循环对象时,无法从中删除对象 通过[copy]而不是循环可以修复它 然而,我有一些未回答的问题,我想从Objective-C专家那里得到一些意见 在第一个for循环中,我希望每个nextObjects指向不同的内存(即我认为msgDetail数组将有一个指针列表,每个指针指向特定数组索引包含的NSDictionary的地址)。但是所有的%p nextoObject打印都给出了相同的值。为什么呢 for(NSDictionary *ne

我学到了一个艰难的方法,即当您在
NSMutableArray
中循环对象时,无法从中删除对象

通过
[copy]
而不是
循环可以修复它

然而,我有一些未回答的问题,我想从Objective-C专家那里得到一些意见

  • 在第一个for循环中,我希望每个
    nextObject
    s指向不同的内存(即我认为
    msgDetail
    数组将有一个指针列表,每个指针指向特定数组索引包含的
    NSDictionary
    的地址)。但是所有的
    %p nextoObject
    打印都给出了相同的值。为什么呢

    for(NSDictionary *nextObject in msgDetailArray)
    {
    
        NSLog(@"Address = %p, value = %@",&nextObject,nextObject) ;
        //Doing [msgDetailArray removeObject:nextObject] here based on some condition fails
    }
    
  • 在第二个for循环中,
    nextObject
    NSDictionary
    s的地址与第一个for循环中打印的地址不同

    for(id nextObject in [msgDetailArray copy])
    {
    
        NSLog(@"In copy Address = %p, value = %@",&nextObject,nextObject) ;
    
        //Doing [msgDetailArray removeObject:nextObject] here based on some condition succeeds and it also removes it from the original array even though I am looping through a copy
    }
    
  • 但是,当我在
    [msgDetailArray copy]
    中循环,然后执行
    removeObject:
    时,它会将其从原始
    msgDetailArray
    中删除。
    如何删除对象:
    执行此操作?它是否实际使用字典的内容并删除与内容匹配的对象?我认为它所做的只是检查是否有一个对象位于同一内存位置并将其删除(基于2,我假设
    [msgDetailArray copy]
    中包含字典的内存地址与原始
    msgDetailArray
    中的地址不同)。如果它实际使用的是内容,我将不得不非常小心,以防有重复条目

    for(id nextObject in msgDetailArray)
    {
            NSLog(@"Address = %p, value = %@",&nextObject,nextObject) ;
            //test what is left in msgDetailArray.  I see that doing removeObject on [msgDetailArray copy] does remove it from the original too.  How is removeObject working (is it actually contents of dictionary)
    }
    
  • 复制数组会执行“浅复制”。它创建一个新的数组对象,然后存储指向第一个数组中对象的指针。它不会创建新对象

    将数组想象成地址簿。它列出了你朋友家的地址。如果我复制了你的地址簿,那么我就有一份地址列表。地址簿中没有房屋

    如果我从通讯簿副本中删除某个条目,它不会从您的通讯簿中删除相同的条目。它也不会摧毁任何房屋

    在循环2代码中,您在副本中循环,然后告诉原始数组删除某些对象。它们将从原始阵列中删除,但不会从副本中删除。(这很好,因为正如您所说,在遍历数组时对其进行变异会导致崩溃。)

    请注意,数组可以包含多个指向同一对象的指针,就像地址可以多次包含同一地址一样。(如果一个朋友在结婚时更改了她的名字,你可以用他结婚的名字把她写进你的地址,并用她的婚前姓留下条目。两个地址都指向同一所房子。)

    请注意,您正在使用的
    removeObject
    方法将删除对象的所有条目。就像你说的“删除我在Elm street 123的地址簿中的所有条目”。如果只想删除重复集的一个条目,则需要使用removeObjectAtIndex,并且需要更改代码以使其正常工作

  • 复制操作复制容器,而不是其内容。您有一个指向相同对象的指针的新列表

  • &nextObject
    是变量的地址,而不是对象的地址。对象的地址是变量的值:
    NSLog(@“%p”,nextObject)

  • removeObject:
    使用将其参数与集合的内容进行比较,后者通常不按地址进行比较,而是按类定义的某种语义赋值进行比较

  • 即使不考虑在快速枚举循环中禁止变异,也无法从副本中删除对象,因为
    copy
    生成不可变的副本。您需要
    mutableCopy
    才能更改新实例

    但是所有的
    %p
    s打印都给出了相同的值。为什么呢

    for(NSDictionary *nextObject in msgDetailArray)
    {
    
        NSLog(@"Address = %p, value = %@",&nextObject,nextObject) ;
        //Doing [msgDetailArray removeObject:nextObject] here based on some condition fails
    }
    
    因为
    &nextObject
    nextObject
    变量的地址,在代码示例中使用循环变量;它的类型是指向指针的指针
    nextObject
    本身也是一个指针,因此如果要打印对象的地址,只需将其强制转换为
    void*

    NSLog(@"Address = %p, value = %@", (void*)nextObject, nextObject);
    
    在第二个for循环中,
    nextObject
    nsdictionary
    的地址与第一个for循环中打印的地址不同

    因为这是另一个变量的地址

    当我在
    [msgDetailArray copy]
    中循环,然后执行
    removeObject
    时,它会将其从原始
    msgDetailArray
    中删除

    正在循环的副本位于不可见的临时对象中。它是由原始数组支持的不可变副本

    调用
    [msgDetailArray removeObject:nextObject]
    在原始数组上运行。如果不希望出现这种效果,请将副本存储在变量中,然后从中删除项目:

    NSMutableArray *mutableCopy = [msgDetailArray mutableCopy];
    ...
    [mutableCopy removeObject:nextObject];
    

    这将不会触及原始阵列。但是,您不能在删除项目的同时迭代
    mutableCopy

    很好的解释。为了确认调用[removeObject:]时,它知道要删除哪个对象,因为它正在使用NSMutableDictionary的内容。对吗?如果是,我假设这只适用于某些对象,如NSDictionary,而不是所有对象。是否有一些术语我可以寻找(如符合NSCopying协议),我可以用来区分我处理的是哪种对象?所有伟大的解释,我不知道接受哪一个!明天之前我会接受一个最高票数的
    removeObject:
    对数组中的所有对象进行循环,并将每个对象与您创建的对象进行比较