【问题标题】:iOS - App crashes Garbagecollector's fault?iOS - 应用程序崩溃 Garbagecollector 的错?
【发布时间】:2012-05-01 19:31:15
【问题描述】:

我和我的团队正在开发一个测验应用程序,我们有 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' * 首先抛出调用栈: (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;

}

【问题讨论】:

  • “无效果”是指无论你做什么代码仍然以同样的方式失败?您能否 - 明天,如果需要 - 发布失败的实际代码以及您遇到的确切错误?
  • 我的意思是清理项目或在真正的 iPad 设备上运行它没有效果。是的,它仍然失败了。好的,我会这样做,但只是给我一些希望:是否可以通过代码重置应用程序?或者在按下按钮时以某种方式触发垃圾收集器?
  • 你的程序中很可能有一个错误(或者至少有一些代码假设它只被调用一次);在这里尝试重置应用似乎是错误的解决方案。
  • 谢谢你,我明天用代码编辑这篇文章。我要不要在下面发表评论,以便您收到通知?
  • 您的异常发生在对 objectAtIndex 的调用中。您对objectAtIndex 的所有调用,除非我错过了一个,都在对数据库查询的结果进行操作。实际问题是否可能是由于某种原因,这些数据库查询之一没有返回任何结果?您可以尝试记录sqlquery 调用的结果。

标签: ios crash garbage-collection alloc


【解决方案1】:

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 ——因此您需要先检查长度。

【讨论】:

  • 是的,我知道,因为 java ,我就是这么称呼它的:P 但我显然不知道所有其他的东西。我明天去看看,非常感谢!
  • 您好,代码已经上线了,可惜不是EXC_BAD_ACCESS
【解决方案2】:

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

【讨论】:

  • 属性已经设置为nonatomic,retain =/我的代码在贴里了,大家可以看看:)
猜你喜欢
  • 1970-01-01
  • 2012-03-27
  • 2013-07-07
  • 2016-09-22
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多