【问题标题】:Compare NSArray with NSMutableArray adding delta objects to NSMutableArray比较 NSArray 和 NSMutableArray 将增量对象添加到 NSMutableArray
【发布时间】:2010-03-11 02:55:07
【问题描述】:

我有一个NSMutableArray,其中填充了字符串对象。为简单起见,我们将说对象是一个人,每个人对象都包含有关该人的信息。

因此我会有一个 NSMutableArray 填充了个人对象:

person.firstName
person.lastName
person.age
person.height

等等。

初始数据源来自网络服务器,并在我的应用程序加载并完成与服务器的初始化时填充。我的应用程序会定期轮询服务器以获取最新的名称列表。

目前我正在创建结果集的NSArray,清空NSMutableArray,然后用NSArray 结果重新填充NSMutableArray,然后销毁NSArray 对象。

这在某些层面上对我来说似乎效率低下,并且还给我带来了丢失表行引用的问题,我可以解决这个问题,但这样做可能会为自己创造更多的工作。

效率低下似乎是我应该能够比较两个数组并最终得到过滤的NSArray。然后我可以将过滤后的集合添加到NSMutableArray。这意味着我可以简单地将新数据附加到NSMutableArray,而不是丢弃所有内容并重新填充。

相反,我需要反向执行相同的过滤器,以查看是否有需要从 NSMutableArray 中删除的记录。

有什么方法可以更有效地做到这一点吗?我是否忽略了文档中某些地方提到了一种更简单的技术?

我在清空NSMutableArray 并重新填充时遇到问题,因为任何引用表都会丢失其选定的行状态。我可以跟踪它并重新选择它,但我的理论是使用某种形式的比较和添加对象和删除对象而不是在一个块中处理整个数组可能意味着我保留我的行引用(假设该项目不是当然删除)。

非常感谢任何建议或帮助。

更新

对每个比较每个订单项进行快速枚举会不会和我一样快?这似乎是一个昂贵的操作,但使用最后一个快速枚举代码可能会非常高效......

解决方案

我最终接受了 Abizem 的建议。在处理大量数据时,创建数组的可变副本和对象的副本似乎比使用 sbooth 的解决方案稍微快一些。两者都工作得很好,我只是通过使用可变复制方法获得了更多优势。话虽如此,它确实让我看到了我以前没有看过的 NSSet。

感谢您的反馈。

【问题讨论】:

  • 为什么不测试一下看看呢?不要过早优化。
  • 在这个过程中:-)我会更新我的发现但是如果有人这样做并且知道......好吧......:-)

标签: objective-c cocoa compare nsmutablearray nsarray


【解决方案1】:

您可以使用 NSSet 轻松完成此类事情(假设您的 person 对象是唯一的):

NSSet *existingItems = [NSSet setWithArray:existingItemArray];
NSSet *newItems = /* Get the new items from the server */

// Determine which items were removed
NSMutableSet *removedItems = [NSMutableSet setWithSet:existingItems];
[removedItems minusSet:newItems];

// Determine which items were added
NSMutableSet *addedItems = [NSMutableSet setWithSet:newItems];
[addedItems minusSet:existingItems];

// Modify the original array
[existingItemArray removeObjectsInArray:[removedItems allObjects]];
[existingItemArray addObjectsFromArray:[addedItems allObjects]];

如果性能不佳,我会感到惊讶,因为我确信实现已经过优化。

【讨论】:

  • 感谢 sbooth 的建议。我没有考虑过使用 NSSet,但是这种方法对于更有效的方法来说是有意义的。我可能拥有大量数据,因此我获得的所有效率提升都会有所帮助。
  • 虽然我没有问这个问题,但这正是我过去一天半以来一直在尝试做的事情,但绝对没有运气。这是一段优雅的代码,我立即意识到这是我需要的。非常感谢,在我差点把笔记本电脑扔出窗外的那一刻,这真是天赐之物! :D
  • 这太棒了!有没有一种简单的方法来获取一个包含尚未添加或删除的项目(即相同)的 NSSet。这样我就可以遍历它并对其执行一些操作。我想我正在寻找包含“重复”的第三个数组/集
  • @Lee NSMutableSet *duplicateItems = [NSMutableSet setWithSet:newItems]; [duplicateItems intersectSet:existingItems];
【解决方案2】:

两点。

  1. 新的 NSArray 包含您需要显示的所有数据。这就是为什么您要在 NSMutableArray 中添加和删除以匹配新的。
  2. 您不想丢失表中行的选定状态。

这是我的建议

  1. 而不是清空 NSMutableArray 并用新数组重新填充它;为什么不创建 NSArray 的 mutableCopy 并将其设置为新的 NSMutableArray?
  2. 不必担心项目的顺序(以及因此选择的行号);如何创建所选对象的副本,并在步骤 1 中创建新的 NSMutableArray 后,在新数组中找到匹配的对象并使用其新索引将其设置为表中的选定行。

【讨论】:

  • Abizem... 喜欢这种方法。至少这样我不需要比较每个数组中的每个项目。即使我采取了NSSet 方向sbooth 的建议,它仍在进行比较。这种方法意味着我只需要设置一次选定的索引,然后就完成了。我将实现每一个,看看我是否会在使用其中一个时获得视觉/性能差异。
  • Hooligancat...另外,如果您正在对对象的相等性进行任何类型的比较,请务必为您的对象类编写isEqualTo: 方法。例如NSString 具有isEqualToString 方法,该方法确保字符串值相同,而不是看到NSString * 指针相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 2011-08-22
相关资源
最近更新 更多