我和我的团队正在开发一个测验应用程序,我们有一个视图,我们只需在标签和按钮上重新加载文本。 现在,当我们开始测验时,有2个循环从数据库加载问题和回答。在这些循环中,我们初始化在.h文件中声明的对象。 所以我们做的是:obj = [[class alloc] initwith:stuff]; 它完美地工作,直到第6次我们调用2循环的方法。有时它会在第一个循环中崩溃,有时会在第二个循环中崩溃。 现在奇怪的是,如果我们在“再次播放”按钮上调用该方法两次它将在第3次崩溃(方法称为6次然后=崩溃),所以我们认为它与内存有关或所以。 我们尝试清理项目,在iPad和模拟器上运行它。没有效果。 错误消息是我们在第一个循环中填充的数组在第二个循环中是空的。
我暂时无法给你一个代码管,但最简单的方法是在用户按下“再次播放”按钮时重置应用程序。有没有简单的方法来做到这一点? 如果应用程序只是关闭并重新打开闪屏,那也没关系。
如果您现在无法提出任何建议,我明天会添加一个代码
提前致谢
编辑: SIGABRT 这是错误消息:SoccerQuiz [1563:f803] *由于未捕获的异常'NSRangeException'终止应用程序,原因:'* - [__ NSArrayM objectAtIndex:]:索引0超出空数组的边界' * 第一次抛出调用堆栈: (0x159e022 0x172fcd6 0x158ad88 0x4719 0x3455 0x159fe99 0xe214e 0xe20e6 0x188ade 0x188fa7 0x188266 0x1073c0 0x1075e6 0xeddc4 0xe1634 0x1488ef5 0x1572195 0x14d6ff2 0x14d58da 0x14d4d84 0x14d4c9b 0x14877d8 0x148788a 0xdf626 0x20ed 0x2055) 终止调用抛出异常(lldb)
我的代码:
-(NSMutableArray*) readFromDatabase{
//if modus is true 20 questions will be loaded(untested). we set mds to 10 for now which works for the first 5 times and then crashes the 6th time
int mds = 0;
if (modus)
mds = 20;
else mds = 10;
bool loop = true;
//a_data is the array in which the data object is. it is filled with the questions and answeres
NSMutableArray * a_data = [[NSMutableArray alloc] init];
//check_id is the array in which the question ids from the database are saved
NSMutableArray * check_id = [[NSMutableArray alloc] init];
//ant is the array in which the 4 possible answers are saved.
NSMutableArray *ant = [[NSMutableArray alloc] init];
//in id_frage the id of the question is saved and in frage the question itself
NSString *id_frage = [[NSString alloc] init];
NSString *frage = [[NSString alloc] init];
//in sql_id the statement for the question is saved
NSString *sql_id = [[NSString alloc] initWithFormat:@"select id from QQUESTION where level = %@ order by random() limit 1", difficulty];
//in the method sqlquery we get data from the database
id_frage = [[self sqlquery: sql_id with:@"Q"] objectAtIndex:0];
[check_id addObject:id_frage];
NSLog(@"1");
//we use these loops to read unique question ids from the database, as you can see random questions are loaded from the database (sql_id statement)
for (int z = 0; z < mds; z++)
{
while (loop)
{
for (int y = 0; y <= check_id.count; y++)
{
//this loop checks if the question id is already in check_id
if ([[check_id objectAtIndex:y] isEqualToString:id_frage])
{
id_frage = [[self sqlquery: sql_id with:@"Q"] objectAtIndex:0];
break;
}
else {
//if the id doesnt already exit, it will be added to the check_id array
if (y == check_id.count-1)
{
[check_id addObject:id_frage];
loop = false;
break;
}
}
}
}
loop = true;
id_frage = [[self sqlquery: sql_id with:@"Q"] objectAtIndex:0];
}
NSLog(@"2");
//this loops loads the questions and answers that fit to the question ids
for (int x = 0; x < mds; x++)
{
//sql_q statement for the questions
NSString *sql_q = [[NSString alloc] initWithFormat:@"select TEXT from QQUESTIONTEXT where ID_QUESTION = '%@' and LANGUAGE = '%@'", [check_id objectAtIndex:x], language];
frage = [[self sqlquery:sql_q with:@"Q" ]objectAtIndex:0];
//sql_a statement for the answers
NSString *sql_a = [[NSString alloc] initWithFormat:@"select answer.correct, answertext.text from QANSWER as answer, QANSWERTEXT as answertext where answer.ID_QUESTION='%@' and answer.ID = answertext.ID_ANSWER and answertext.LANGUAGE = '%@'", [check_id objectAtIndex:x], language];
ant = [self sqlquery: sql_a with:@"A"];
//this loop sets the right answer at the first position of the array
for(int a = 0; a<ant.count-1; a++)
{
if([[ant objectAtIndex:a] isEqualToString:@"1"])
{
a++;
NSString *h = [[NSString alloc]initWithFormat:[ant objectAtIndex:1]];
[ant replaceObjectAtIndex:1 withObject:[ant objectAtIndex:a]];
[ant replaceObjectAtIndex:a withObject:h];
a--;
break;
}
}
//this data object 'd' is filled with a question and 4 answers and 10 or 20 will be added to a_data which will be returned
d = [[data alloc] initFrage:frage mitAntwort1:[ant objectAtIndex:1] Antwort2:[ant objectAtIndex:3] Antwort3:[ant objectAtIndex:5] Antwort4:[ant objectAtIndex:7]];
[a_data addObject:d];
}
NSLog(@"3");
return a_data;
}
答案 0 :(得分:3)
iOS上没有垃圾收集器 - 有手动或自动引用计数(ARC)。在任何一种情况下,都使用retain和release对对象进行引用计数。使用ARC,您不必自己进行这些调用,但这并不意味着您仍然无法遇到问题。
如果没有您的代码或任何信息,我只能提供一般性建议。我假设您的崩溃是EXC_BAD_ACCESS或某些等效的。
我写了一篇博客来解释这个问题以及如何排除故障
http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
在你的情况下,这就是我要做的事情
如果失败,请打开Debug Malloc并使用我博客中链接的工具来调试问题。
基于问题编辑的编辑:
你得到一个例外 - 在你提供的代码中,有几个objectAtIndex调用 - 使用这里的指令在异常上创建一个断点:
http://www.dosomethinghere.com/2011/04/18/xcode-4-exception-breakpoint/
告诉我们确切的行。
基本上,你不能在空数组上调用objectAtIndex为0 - 所以你需要先检查长度。
答案 1 :(得分:0)
在iOS中没有垃圾收集器功能。
相反,有ARC(自动参考计数)
Apple在这里讨论ARC:https://developer.apple.com/technologies/ios5/
ARC是编译器技术,使用保留计数来跟踪对象
因此,应用程序崩溃的最可能原因是访问已发布的对象。
这通常会导致编译器警告您访问不良!
在头文件中,确保使用
正确保留对象
@property(nonatomic,retain)Object * myobject;
希望这有帮助!