当处理大量元素时,我常常遇到一些方法和操作的内存问题。就我而言,我有大约10万个元素的数组。有几个操作导致内存过量,我想知道优化它们的最佳方法。
我正在使用XCode 5.1.1并打开ARC。
以下是几个样本:
1)在NSMutableArray中添加大量元素。
如果检查了某些条件,我需要在数组中添加多个元素:
for(NSString* value in files) {
if (!condition) {
[filesToRemove addObject:value];
}
}
文件中的元素数量约为50K - 100K。此示例将导致内存过量。 RAM的使用将开始增加算术级数。所以,为了防止这种情况,我可以把它包装成@autoreleasepool
for(NSString* value in files) {
@autoreleasepool {
if (!condition) {
[filesToRemove addObject:value];
}
}
}
我在这个问题上发现了类似的问题:Do loops and convenience methods cause memory peaks with ARC?
因此,使用@autoreleasepool
可以解决这个问题。有更好的解决方案吗?
2)从数组中减去数组。
这个更棘手。我有两个数组,第一个是大约100K,第二个是大约50K,我需要从另一个中减去。
首先尝试:
[files removeObjectsInArray:filesToRemove];
这会导致内存过度杀伤。为什么会这样?在我看来,removeObjectsInArray
方法与1)具有相同的行为。我不知道这个方法是如何工作的,但我可以想象,基本上,我们只是在循环中经历一个数组,然后在循环中遍历第二个数组并检查array1中的当前元素是否等于每个元素数组2。
在伪代码中,它看起来像那样:
for (int i = 0; i < files.count; i++)
{
for (int j = 0; j < filesToRemove.count; j++)
{
if ([filesToRemove[j] isEqualTo:files[i]])
{
[files removeObject:filesToRemove[j]];
// perhaps break here?
}
}
}
我是对的吗?如果我在代码中使用此代码代替removeObjectsInArray
并使用@autoreleasepool
,那么会产生与removeObjectsInArray
方法相同的效果吗?
更新:我已经在@autoreleasepool尝试了这个,但它没有用。内存使用量仍在增加。关于从大型数组中除外对象的任何想法?
我的问题是:
如何解决问题№2?
使用如此大量数据的最佳方法是什么?这些数组通常包含字符串值。也许使用NSMutableDictionary而不是NSMutableArray会更快?因为,即使我解决内存使用问题,这些操作的速度仍然很慢。