0

我和我的团队正在开发一个测验应用程序,我们有 1 个视图,我们只需重新加载标签和按钮上的文本。现在,当我们开始测验时,有 2 个循环从数据库中加载问题和答案。在这些循环中,我们初始化在 .h 文件中声明的对象。所以我们要做的是: obj = [[class alloc] initwith:stuff]; 在我们第 6 次调用 2 个循环所在的方法之前,它一直运行良好。有时它在第一个循环中崩溃,有时在第二个循环中崩溃。现在奇怪的是,如果我们在“再次播放”按钮上调用该方法两次,它会在第三次崩溃(方法调用 6 次然后 = 崩溃),所以我们认为它与内存或所以。我们尝试清理项目,在 iPad 和模拟器上运行它。没有效果。错误消息是我们的数组

目前我不能给你一个代码片段,但最简单的方法是在用户按下“再次播放”按钮时简单地重置应用程序。有什么简单的方法可以做到这一点?如果应用程序只是关闭并使用启动画面重新打开,那也很好。

如果你现在不能提出任何建议,我明天会添加代码片段

提前致谢

编辑:SIGABRT 这是错误消息:SoccerQuiz[1563:f803] * 由于未捕获的异常 'NSRangeException' 导致应用程序终止,原因:'* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array' * First throw call stack : (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) terminate called throwing an exception(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;

}

4

2 回答 2

3

iOS 上没有垃圾收集器——有手动或自动引用计数 (ARC)。在任何一种情况下,对象都通过使用保留和释放进行引用计数。使用 ARC,您不必自己拨打这些电话,但这并不意味着您仍然不会遇到问题。

没有您的代码或任何信息,我只能提供一般性建议。我假设您的崩溃是 EXC_BAD_ACCESS 或等效的。

我写了一篇博客来解释这个问题以及如何解决它

http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html

在你的情况下,这就是我会做的

  1. 运行分析并修复它标记的每个问题
  2. 打开僵尸并重现您的问题。如果您正在与僵尸对象交谈,现在应该更容易看到发生了什么。

如果失败,则打开 Debug Malloc 并使用我博客中链接的工具来调试问题。

根据问题编辑:

你得到一个异常——在你提供的代码中,有几个 objectAtIndex 调用——使用这里的指令在异常上创建一个断点:

http://www.dosomethinghere.com/2011/04/18/xcode-4-exception-breakpoint/

并告诉我们确切的路线。

基本上,您不能在空数组上调用 0 的 objectAtIndex ——因此您需要先检查长度。

于 2012-05-01T20:13:21.233 回答
0

在 iOS 中没有垃圾收集器功能。
相反,有 ARC(自动引用计数)
Apple 在此处讨论 ARC:https
://developer.apple.com/technologies/ios5/ ARC 是编译器技术并使用保留计数来跟踪对象因此,最可能的原因是应用程序崩溃正在访问已释放的对象。这通常会导致编译器警告您访问不正确!在头文件中,确保使用
@property(nonatomic,retain)Object* myobject;正确保留您的对象。
希望这有帮助!

于 2012-05-01T20:15:28.497 回答