释放一个NSMutableArray导致EXC_BAD_ACCESS错误

问题描述:

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

有什么想法?

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; 

    } 

你的问题在于这部分代码:

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

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

第一行分配一个新RetrievedAnalysisData,但随后的第二抛出远(泄漏的话),并把对象取出从数组代替retrievedAnalysisData变量。您不拥有从数组中获取的此对象,并且您不通过调用retain获取所有权。所以第四行的release是不正确的,释放一个你不拥有的对象。

然后,当你释放你的NSMutableArray时,它会尝试再次释放该对象,并且因为该对象已经释放而发生崩溃。

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

+0

好的,改变了代码,它的工作。进行分析并发布数据列表,泄漏消失了!非常感谢你,这是我在代码中的几个地方遇到的问题,所以我非常感激。我对obj-c和学习还很陌生,刚开始使用自定义对象。 你能否进一步解释原代码中会发生什么?我创建了一个新的RetrievedAnalysisData对象,但是当我尝试从我的sortedRetrievedAnalysisDataList中为它分配一个RetrievedAnalaysisData对象时,我该如何将它扔掉? – Log139

不知道你的所有属性的内存管理,很难看到究竟发生了什么。但这里看看:

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]; 
    }