在循环过程中,我的应用程序崩溃而没有错误。数组计数等于175260.使用分析器我没有泄漏,所以我不知道为什么App退出,可能在很长一段时间内CPU使用率为100%?
感谢您的帮助。
以下代码崩溃App:
for(unsigned int i = 0; i <14;i++)
{
if(findSensor[i]==YES)
{
for(unsigned int j = 1; j <[array count];j++)
{
@autoreleasepool {
if([[[[array objectAtIndex:j] componentsSeparatedByString:@";"] objectAtIndex:0] isEqualToString:[NSString stringWithFormat:@"%d",10*(i+1)]])
{
//Code here
}
}
}
}
}
完整的代码是:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [NSString stringWithFormat:@"%@/%@",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase];
NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:fileName];
NSFileHandle *output = [NSFileHandle fileHandleForReadingAtPath:[NSString stringWithFormat:@"%@/%@10",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase]];
if(output == nil)
{
NSManagedObjectContext *context = [self managedObjectContext];
_recordlocal = [NSEntityDescription insertNewObjectForEntityForName:@"RECORD" inManagedObjectContext:context];
_recordlocal.date = [ibNavSettings interfaceSettings].selectedFileToDataBase;
NSData *inputData = [NSData dataWithData:[fh readDataToEndOfFile]];
NSString *inputString = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding];
NSArray *array = [[NSArray alloc] initWithArray:[inputString componentsSeparatedByString:@"\n"]];
for(unsigned int i = 0; i <14;i++)
{
if(findSensor[i]==YES)
{
[[NSFileManager defaultManager] createFileAtPath:[NSString stringWithFormat:@"%@/%@%d",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase,10*(i+1)] contents:nil attributes:nil];
NSMutableString *saveString = [[NSMutableString alloc] init];
int count = 0;
for(unsigned int j = 1; j <[array count];j++)
{
@autoreleasepool {
if([[[[array objectAtIndex:j] componentsSeparatedByString:@";"] objectAtIndex:0] isEqualToString:[NSString stringWithFormat:@"%d",10*(i+1)]])
{
[saveString appendString:[array objectAtIndex:j]];
[saveString appendString:@"\n"];
if(i == 0)
count++;
progress++;
pourcent = progress/total;
load = pourcent*100;
if(load%5==0)
[self performSelectorInBackground:@selector(changeUI:)withObject:[NSNumber numberWithFloat:(pourcent)]];
}
}
}
[saveString writeToFile:[NSString stringWithFormat:@"%@/%@%d",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase,10*(i+1)] atomically:YES encoding:NSUTF8StringEncoding error:nil];
if(i == 0)
_recordlocal.count = [[NSNumber alloc] initWithInt:(count/50)];
}
}
_recordlocal.load = [[NSNumber alloc] initWithBool:YES];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Core data error %@, %@", error, [error userInfo]);
abort();
}
答案 0 :(得分:2)
我猜你的应用程序崩溃没有可读的异常,因为它的可用内存不足,特别是因为你指出它正在运行大量的迭代。
对于测试,我建议做Rikkles建议的自动释放池。另外,由于i的值(以及比较字符串的结果)很少改变,我也会在j循环之外创建该字符串。这样可以避免产生大量额外的字符串。
除此之外,因为看起来你正在寻找一个由分号分隔的字符串开头的字符串,我建议不要使用componentsSeparatedByString而是检查元素零,你使用NSString方法hasPrefix来检查对于你正在寻找的条件。
以下是一个例子:
for(unsigned int i = 0; i <14;i++)
{
NSString *searchString = [NSString stringWithFormat:@"%d;", 10*(i+1)];
if(findSensor[i]==YES)
{
for(unsigned int j = 1; j <[array count];j++)
{
if([[array objectAtIndex:j] hasPrefix:searchString])
{
//Code here
}
}
}
}
(我希望这可以编译并运行,如果没有,它应该需要的不仅仅是微调。我现在远离我的Mac。)
如果这没有帮助,那么//代码里面发生的事情必定是罪魁祸首。
答案 1 :(得分:1)
为什么要创建[array count]
autoreleasepool?创造这么多人的意义何在?因此可能会崩溃。将@autoreleasepool
置于for循环之外。
我认为你会这样做的唯一原因是,如果你在for循环的每次迭代中创建了这么多瞬态对象,那么一旦你离开迭代,你就想要摆脱它们。但还有其他方法可以做到这一点,包括在每次迭代中重用这些对象。
答案 2 :(得分:0)
对内循环使用快速枚举,实际上并没有使用索引'j'来代替
放置一些NSLog,它会减慢一切,但你需要弄清楚你失败的地方。这将有助于指出每个人都朝着正确的方向前进。
实际使用NSError对象并在抛出错误时输出它们的值:
NSError *writeError = nil;
[saveString writeToFile:[NSString stringWithFormat:@"%@/%@%d",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase,10*(i+1)]
atomically:YES
encoding:NSUTF8StringEncoding
error:&writeError];
if(error != nil) NSLog(@"error writing file: %@", [[writeError userInfo]description]);
您似乎尝试从后台线程更新UI。这将无法工作或将导致崩溃。 UI代码只能从主线程调用。所以不要这样做:
[self performSelectorInBackground:@selector(changeUI:)withObject:[NSNumber numberWithFloat:(pourcent)]];
如果您已经在后台线程上,这可能会崩溃,因为您在线程上的线程上创建线程。你想要打电话:
[self performSelectorOnMainThread:@selector(changeUI:)withObject:[NSNumber numberWithFloat:(pourcent)]];
你可能会超过NSString的最大长度(它很大但我之前做过一次)。您应该只是在循环的每次迭代中附加文件,因此您没有不断增长的NSMutableString:
NSString *path = [NSString stringWithFormat:@"%@/%@%d",documentsDirectory,[ibNavSettings interfaceSettings].selectedFileToDataBase,10*(i+1)]
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:filePath];
NSData *newLine = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
for(NSString *rowString in array)
{
if([[[rowString componentsSeparatedByString:@";"] objectAtIndex:0] isEqualToString:[NSString stringWithFormat:@"%d",10*(i+1)]])
{
NSData *stringData = [rowString dataUsingEncoding:NSUTF8StringEncoding];
[fh truncateFileAtOffset:[fh seekToEndOfFile]];
[fh writeData:stringData];
[fh truncateFileAtOffset:[fh seekToEndOfFile]];
[fh writeData:newLine];
if(i == 0)
count++;
progress++;
pourcent = progress/total;
load = pourcent*100;
if(load%5==0)
[self performSelectorOnMainThread:@selector(changeUI:)withObject:[NSNumber numberWithFloat:(pourcent)]];
}
}
}
这有助于你放弃autoreleasepools
如果您的阵列实际上有175260行,那可能就是您的问题。您使用unsigned int作为索引var进行循环。 c中的无符号整数的最大值为65535.使用unsigned long int,最大值为4294967295。