【问题标题】:releasing a NSMutableArray is causing EXC_BAD_ACCESS error释放 NSMutableArray 导致 EXC_BAD_ACCESS 错误
【发布时间】:2011-07-15 20:07:11
【问题描述】:

所以当我尝试运行以下代码时,我最终会遇到 EXC_BAD_ACCESS 错误。当我尝试释放 NSMutableArray 检索分析数据列表时会发生这种情况。该数组是检索到的AnalysisData 对象的列表。如果我尝试释放数据列表,或者如果我使用自动释放设置初始化,我会得到相同的结果。我有点猜测它与代码的排序部分有关,因为我对检索的AnalysisIDarray 没有这个问题。

有什么想法吗?

if (tempDict != NULL) 
    {
        NSMutableArray *retrievedAnalysisDataList = [[NSMutableArray alloc] init];
        NSMutableArray *retrievedAnalysisIDarray = [[NSMutableArray alloc] init];

        for (id key in tempDict)
        {
            retrievedAnalysisData = [[RetrievedAnalysisData alloc] init];

            retrievedAnalysisData.createDate = [[tempDict objectForKey:key] objectForKey:@"createdate"];
            retrievedAnalysisData.ID = [[tempDict objectForKey:key] objectForKey:@"id"];
            retrievedAnalysisData.mode = [[tempDict objectForKey:key] objectForKey:@"mode"];
            retrievedAnalysisData.name = [[tempDict objectForKey:key] objectForKey:@"name"];
            retrievedAnalysisData.numZones = [[tempDict objectForKey:key] objectForKey:@"numzones"];
            retrievedAnalysisData.srcImg = [[tempDict objectForKey:key] objectForKey:@"srcimg"];
            retrievedAnalysisData.type = [[tempDict objectForKey:key] objectForKey:@"type"];

            //NSLog(@"\n createDate: %@ \n id: %@ \n mode: %@ \n name: %@ \n numzone: %@ \n srcimg: %@ \n type: %@", retrievedAnalysisData.createDate, retrievedAnalysisData.ID, retrievedAnalysisData.mode, retrievedAnalysisData.name, retrievedAnalysisData.numZones, retrievedAnalysisData.srcImg, retrievedAnalysisData.type);

            [retrievedAnalysisDataList addObject:retrievedAnalysisData];
            [retrievedAnalysisData release];
        }

        NSSortDescriptor *sortDescriptor;
        sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"createDate" ascending:YES] autorelease];
        NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
        NSArray *sortedRetrievedAnalysisDataList;
        sortedRetrievedAnalysisDataList = [retrievedAnalysisDataList sortedArrayUsingDescriptors:sortDescriptors];

        int count = [sortedRetrievedAnalysisDataList count];

        for (int i = 0; i < count; i++) {
            retrievedAnalysisData = [[RetrievedAnalysisData alloc] init];
            retrievedAnalysisData = [sortedRetrievedAnalysisDataList objectAtIndex:i];

            [retrievedAnalysisIDarray addObject:retrievedAnalysisData.ID];
            [retrievedAnalysisData release];
        }

        dataCenter.sortedRetrievedAnalysisDataList = sortedRetrievedAnalysisDataList;
        dataCenter.retrievedAnalysisIDarray = retrievedAnalysisIDarray;

        [retrievedAnalysisIDarray release];
        [retrievedAnalysisDataList release];

        dataCenter.isRetrieve = [NSNumber numberWithInt:1];

        [activityIndicator stopAnimating];
        [picker reloadAllComponents];

        picker.hidden = FALSE;
        pickerToolBar.hidden = FALSE;
        toolBar.hidden = TRUE;
        innerCircle.hidden = TRUE;
        outerCircle.hidden = TRUE;
        trackLabel.hidden = TRUE;
        displayGPSLabel.hidden = TRUE;

    }

【问题讨论】:

    标签: objective-c memory-management nsmutablearray


    【解决方案1】:

    你的问题出在这段代码上:

            retrievedAnalysisData = [[RetrievedAnalysisData alloc] init];
            retrievedAnalysisData = [sortedRetrievedAnalysisDataList objectAtIndex:i];
    
            [retrievedAnalysisIDarray addObject:retrievedAnalysisData.ID];
            [retrievedAnalysisData release];
    

    第一行分配了一个新的 RetrievedAnalysisData,但随后第二行将其丢弃(泄漏)并将从数组中获取的对象放入 retrievedAnalysisData 变量中。您不拥有从数组中获取的这个对象,并且您不会通过调用 retain 获得所有权。所以第四行的release不正确,释放了一个不属于你的对象。

    然后,当您释放 NSMutableArray 时,它会再次尝试释放对象,但由于对象已被释放,您会遇到崩溃。

    要修复它,去掉无用的第一行,同时去掉不正确的发布。

    【讨论】:

    • 好的,改了代码就行了。运行分析并发布数据列表,泄漏消失了!非常感谢,这是我在代码中的几个地方遇到的问题,所以我非常感激。我对 obj-c 和学习还很陌生,刚开始使用自定义对象。您能否进一步解释原始代码中发生的情况?我创建了一个新的 RetrievedAnalysisData 对象,但是当我尝试从我的 sortedRetrievedAnalysisDataList 中为其分配一个 RetrievedAnalaysisData 对象时,我该如何丢弃它?
    【解决方案2】:

    在不了解所有属性的内存管理的情况下,很难确切了解发生了什么。但请看这里:

        for (int i = 0; i < count; i++) {
            retrievedAnalysisData = [[RetrievedAnalysisData alloc] init];
            retrievedAnalysisData = [sortedRetrievedAnalysisDataList objectAtIndex:i];
    
            [retrievedAnalysisIDarray addObject:retrievedAnalysisData.ID];
            [retrievedAnalysisData release];
        }
    

    您在自动释放的对象 (retrievedAnalysisData) 上调用 -release。试试这个:

        for (int i = 0; i < count; i++) {
            retrievedAnalysisData = [sortedRetrievedAnalysisDataList objectAtIndex:i];
    
            [retrievedAnalysisIDarray addObject:retrievedAnalysisData.ID];
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多