【问题标题】:Enumeration and removing a particular object from NSMutableArray从 NSMutableArray 枚举和删除特定对象
【发布时间】:2011-08-20 09:57:03
【问题描述】:

我无法从我的 NSMutableArray 中删除项目。我对 Objective-C 非常陌生,所以请多多包涵。

到目前为止,我有以下内容:如果其中包含某些文本,我正在尝试从数组中删除一行。在快速枚举时我不能这样做,所以我试图存储索引,以便在枚举完成后删除。但是,有人告诉我,这会从没有强制转换的整数中生成一个指针。糊涂了!

//First remove any previous Offending entry.
//Read hostfile into array.
NSString *hostFileOriginalString = [[NSString alloc] initWithContentsOfFile:@"/etc/hosts"];
NSMutableArray *hostFileOriginalArray = [[hostFileOriginalString componentsSeparatedByString:@"\n"] mutableCopy];
NSInteger hostFileOffendingLocation;

//Use a for each loop to iterate through the array.
for (NSString *lineOfHosts in hostFileOriginalArray) {

    if ([lineOfHosts rangeOfString:@"Offending"].location != NSNotFound) {

    //Offending entry found, so remove it.
    //[hostFileOriginalArray removeObject:lineOfHosts];

    hostFileOffendingLocation = [hostFileOriginalArray indexOfObject:lineOfHosts];
    //NSLog(@"%@", hostFileOffendingLocation);
}

}
//Release the Array. 
[hostFileOriginalArray release];

//Remove offending entry from Array.
[hostFileOriginalArray removeObject:hostFileOffendingLocation];

【问题讨论】:

  • 这会在没有强制转换的情况下从整数生成指针,因为您将整数传递给removeObject:。我认为removeObjectAtIndex: 是您所追求的。另外,为什么要在尝试删除对象之前释放数组?

标签: objective-c cocoa nsmutablearray fast-enumeration


【解决方案1】:

我真正的问题是为什么要在修改数组之前释放它

尝试移动

[hostFileOriginalArray release];

到之后

[hostFileOriginalArray removeObject:hostFileOffendingLocation];

【讨论】:

  • 谢谢。我现在改了。但是,原来的问题依然存在。
  • 它是否显示为从可变数组中删除而不是从原始数组中删除,或者它仍然显示在两者中?我怀疑这是因为您正在使用 mutablecopy 并且它正在创建数据的副本
  • hostFileOffendingLocation 是对象的索引,而不是对象本身。你想使用removeObjectAtIndex:,而不是removeObject
  • 是的,我错过了,当我阅读代码太快时会发生这种情况
【解决方案2】:

您可以通过调用[hostFileOriginalArray removeObjectIdenticalTo:@"Offending"]; 来完成此操作而无需循环

请注意,它会删除违规对象的多个实例,但这看起来就像您想要的那样。它还将以快速的方式执行操作,而您不必担心要使用哪个循环的实现细节。

作为一般规则(特别是对于真正常用的对象,如容器和 NSString),请检查类引用以查看 Apple 是否已经有办法做您想做的事情。它使您的代码对其他 Cocoa 用户(包括未来的您)更具可读性,并减少了代码维护——您现在将其留给 Apple 来为他们的代码添加诸如快速枚举之类的新技术,并且当您链接时您可以免费获得它针对新版本的 SDK。

此外,您可能应该在函数末尾返回 hostFileOriginalArray,这样它可以做一些有用的事情 - 您可以将它作为自动释放的对象返回。

【讨论】:

  • removeObjectIdenticalTo 听起来很像我所追求的。但是,我似乎无法让它以与上面代码中的 rangeOfString 相同的方式匹配。正如您可能猜到的那样,代码正在编辑主机文件,该文件将包含一个不断变化的 IP 地址和一个别名。我需要删除 rangeOfString 允许我做的整行。
  • 啊,我错过了它正在寻找 @"Offending" 作为子字符串。尝试构建一个 NSPredicate(也许使用 [NSPredicate predicateWithBlock:] 如果未找到 @"Offending" 则块返回 YES,或者使用在 arstechnica.com/apple/guides/2009/04/… 找到的字符串匹配)。
  • 实际上,我已经能够将有问题的行保存为字符串,然后使用 removeObjectIdenticalTo 将其删除 :) 再次感谢。
  • removeObjectIdenticalTo: 按(id)搜索,即只删除实际对象,不删除具有相同值的对象,请改用removeObject:。
  • 你真的想要 removeObjectAtIndex: 反正。
【解决方案3】:
//Remove offending entry from Array.
[hostFileOriginalArray removeObjectAtIndex:hostFileOffendingLocation];

//Release the Array. 
[hostFileOriginalArray release];

您应该已经收到编译器警告...看看它们,它们通常很有帮助,我总是尝试发出 0 个警告...这样我就知道我在哪里做了粗心的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2011-09-02
    相关资源
    最近更新 更多