我正在尝试遍历一个包含大约6500个项目的NSSet。我正在使用:
for (id Location in sortedArray) {
loc = [sortedArray objectAtIndex:i];
cord = [cord stringByAppendingString:[NSString stringWithFormat:@"%f,%f ",[loc.longitude doubleValue],[loc.latitude doubleValue]]];
i++;
}
这很好用,但似乎不够快。它涉及项目5700,我得到以下错误:
Program received signal: “0”.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")
有没有办法比这更快地循环数据?它需要大约20秒或更长时间,似乎让用户等了这太久了!
想法?
答案 0 :(得分:7)
使用快速枚举设置循环,然后忽略它。
for (id Location in sortedArray) {
loc = [sortedArray objectAtIndex:i];
第一行设置一个名为Location
的循环局部变量,在每次迭代时,它将指向数组中的一个项目。但是您忽略该变量并使用第二个变量loc
,并再次从数组中获取值。你应该把它重写为:
for (id loc in sortedArray) {
cord = [cord stringByAppendingString:...]
}
虽然我们正在努力,但构建cord
字符串的方式却是疯狂的。您将通过循环在每次迭代中创建一个新字符串。使用NSMutableString并在每次迭代时调用appendFormat:
会更聪明。然后,您将不会使用数千个未使用的NSString对象填充自动释放池。所以像这样:
NSMutableString *cord = [NSMutableString string];
for (id loc in sortedArray) {
[cord appendFormat:...];
}
这两项更改都会加快代码速度并显着降低内存使用量,并且可能会消除导致您遇到的奇怪错误的原因。
答案 1 :(得分:6)
三件事:
此外,您似乎正在使用自己的位置类。将其更改为返回双精度而不是(我假设)NSNumber * s。绝对不要退回NSStrings;从字符串转换为double是slooooooow。或者,返回CLLocationCoordinate2D(两个双精度的结构)以避免额外的方法调用。
让我无耻地重写您的代码:
NSMutableString * cord = [NSMutableString stringWithCapacity:cord.count*20];
for (Location * loc in sortedArray) {
[cord appendFormat:@"%f,%f ",[loc.longitude doubleValue],[loc.latitude doubleValue]];
}
答案 2 :(得分:1)
不确定导致程序错误的原因,但有两点可以改进:
使用NSMutableString累积值
NSMutableString *cord = [NSMutableString string];
for (CLLocation* loc in sortedArray) {
[cord appendFormat@"%f,%f ",[loc.longitude doubleValue],[loc.latitude doubleValue]];
}
答案 3 :(得分:0)
看起来你的应用程序在发生迭代时终止了占用主线程。
您应该使用NSOperation
来完成任务并异步执行。您将需要回调主线程以完成,但尝试在主线程上执行此操作是一种破坏的用户体验 - 即使它只需要3秒钟。
答案 4 :(得分:0)
我刚刚遇到一个关于迭代NSSet的有趣(可能鲜为人知)的事实:
快速枚举循环的每次迭代开销因集合类型而异 - 基本上,集合是否强制代码在每次迭代后返回更多元素。对于数组,它没有;对于一套,IIRC它确实如此。这种可能性使得编译器很难在循环的迭代中推理内存(否则这将是快速枚举的一个重要优势),并且在任何一种情况下都会因为强制修改检查而产生额外的开销。
...
根据经验,如果不在数组上进行迭代,则使用块进行迭代几乎总是最佳。
事实上,我发现当你使用NSSet时,使用基于块的方法进行迭代比快速枚举要快一些。它也比在set的allObjects数组上使用快速枚举略快。