释放NSMutableArray导致EXC_BAD_ACCESS错误

时间:2011-07-15 20:07:12

标签: objective-c memory-management nsmutablearray

所以当我尝试运行以下代码时,我最终得到了一个EXC_BAD_ACCESS错误。当我尝试发布NSMutableArray retrieveAnalysisDataList时会发生这种情况。该数组是retrieveAnalysisData对象的列表。如果我尝试释放数据列表或者如果我使用autorelease设置init,我会得到相同的结果。我有点猜测它与代码的排序部分有关,因为我对retrieveAnalysisIDarray没有这个问题。

任何想法?

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;

    }

2 个答案:

答案 0 :(得分:4)

您的问题在于此部分代码:

        retrievedAnalysisData = [[RetrievedAnalysisData alloc] init];
        retrievedAnalysisData = [sortedRetrievedAnalysisDataList objectAtIndex:i];

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

第一行分配一个新的RetrievedAnalysisData,但第二行抛出它(泄漏它)并将一个从数组中取出的对象放在retrievedAnalysisData变量中。您没有拥有从数组中获取的此对象,并且您不通过调用retain来获取所有权。所以第四行的release不正确,释放了一个你不拥有的对象。

然后当您释放NSMutableArray时,它会再次尝试释放该对象,并且因为该对象已经被释放而导致崩溃。

要修复它,摆脱无用的第一行,并摆脱不正确的释放。

答案 1 :(得分:1)

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

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

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

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

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

        [retrievedAnalysisIDarray addObject:retrievedAnalysisData.ID];
    }