向 MutableArray 添加或删除对象时泄漏

Posted

技术标签:

【中文标题】向 MutableArray 添加或删除对象时泄漏【英文标题】:Leaks when adding-removing objects to a MutableArray 【发布时间】:2010-09-20 15:06:05 【问题描述】:

我的应用程序出现内存泄漏。 我的应用程序在 tableviewcontroller 上启动。我解析一个 json 文件来填充一个数组。然后这个数组用于填充 tableview 的单元格。 我用对象(类)填充我的数组。

我愿意:

[tab_Demandes removeAllObjects];

for (NSDictionary *demandeD in demandes)


    Demande *dem =[[Demande alloc] init];

    dem.demTitle=title;

    dem.demId=Id;

    dem.demCreated=created;

    [tab_Demandes addObject:dem];

    [dem release];

我的数组和表格视图在启动时已填满,没问题。 如果我点击一个表格单元格,然后想回到表格视图,我的应用程序崩溃:

[tab_Demandes removeAllObjects];

如果我不执行 [dem release],我每次重新加载 tab_Demandes 时都会出现仪器泄漏。 RemoveAllObjects 工作,但我有泄漏。

感谢您一如既往的帮助。

瓦卢 ++

编辑:这是我制作细胞的地方。也许我在创建单元格时搞砸了 实际上 tab_Demandes 在委托中声明,使用 get/set 从其他类(我加载我的 tableviewcontroller)访问它。

(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

static NSString *CellIdentifier = @"Cell";

CustomCellViewController *cell = (CustomCellViewController *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
   // NSLog(@"Cell created");
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCellViewController" owner:nil options:nil];

    for(id currentObject in topLevelObjects)
    
        if([currentObject isKindOfClass:[CustomCellViewController class]])
        
            cell = (CustomCellViewController *)currentObject;
            break;
        
    


    // Set up the cell...


    TabsAppDelegate *appDelegate = (TabsAppDelegate*)[[UIApplication sharedApplication] delegate];

    cell.lbl_demId.text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row ] demId]];
    cell.lbl_demCopro .text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demIdCopro ]];
    cell.lbl_demImmeuble.text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demIdImmeuble]];
    cell.lbl_demLot.text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demIdLot]];
    cell.lbl_demDescriptif.text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demTitle]];
    //NSLog(@"statut demande : %@",[[tab_Demandes objectAtIndex:indexPath.row] demStatut]);
    if ([[[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demStatut] isEqualToString: @"Validée"])
    
    cell.lbl_ImageView.image=[UIImage imageNamed:@"VDEM2.png"];
    
    if([[[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demStatut] isEqualToString: @"Initiée"])
    
       cell.lbl_ImageView.image=[UIImage imageNamed:@"IDEM.png"];
    
    if([[[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demStatut] isEqualToString: @"Terminée"])
    
    cell.lbl_ImageView.image=[UIImage imageNamed:@"TDEM.png"];
    
    if([[[[appDelegate tab_Demandes] objectAtIndex:indexPath.row] demStatut] isEqualToString: @"En coursée"])
    
    cell.lbl_ImageView.image=[UIImage imageNamed:@"EDEM.png"];
    


return cell;    

新编辑:

Demandes.h:

@interface Demande : NSObject  

    NSString *demId;
    NSString *demStatut;
    NSString *demTitle;
    NSString *demCreated;
    NSString *demIdCopro;
    NSString *demIdImmeuble;
    NSString *demIdLot;
    NSString *demDescriptif;
    NSString *demAuteur;
    NSString *demIdAuteur;
    NSString *demLoginAuteur;   


@property (retain,nonatomic) NSString *demId;
@property (retain,nonatomic) NSString *demIdCopro;
@property (retain,nonatomic) NSString *demIdImmeuble;
@property (retain,nonatomic) NSString *demIdLot;
@property (retain,nonatomic) NSString *demDescriptif;
@property (retain,nonatomic) NSString *demStatut;
@property (retain,nonatomic) NSString *demTitle;
@property (retain,nonatomic) NSString *demCreated;
@property (retain,nonatomic) NSString *demAuteur;
@property (retain,nonatomic) NSString *demIdAuteur;
@property (retain,nonatomic) NSString *demLoginAuteur;
@end

Demandes.m:

import "Demande.h"
@implementation Demande


@synthesize demId,demIdCopro,demIdImmeuble,demIdLot,demDescriptif,demStatut,demTitle,demCreated,demAuteur,demIdAuteur,demLoginAuteur;


- (void)dealloc    
    [demId release];
    [demIdCopro release];
    [demId release];
    [demIdImmeuble release];
    [demIdLot release];
    [demDescriptif release];
    [demStatut release];
    [demTitle release];
    [demCreated release];
    [demAuteur release];
    [demIdAuteur release];
    [demLoginAuteur release];
    [super dealloc];

@end

【问题讨论】:

能分享一下Demande类的代码吗? 【参考方案1】:

上面的代码是正确的。我想知道您是否没有过度释放数组中的对象(即在 tableView:cellForRowAtIndexPath 方法期间)。当调用 removeAllObject 时,该方法释放它删除的每个对象。如果一个对象已经被释放和释放,你的应用就会崩溃。

建议优化:

-确保nib中的cellIdentifier是好的@"Cell"

-替换

cell.lbl_demId.text=[NSString stringWithFormat:@"%@", [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row ] demId]];

通过

Demand* dem = [[[appDelegate tab_Demandes] objectAtIndex:indexPath.row ];
cell.lbl_demId.text=[NSString stringWithFormat:@"%@", [dem demId]];

避免查询数组时间过长。

-避免将模型放在 appDelegate 中,而是创建一个单例模型对象。这是一个常见的初学者设计错误,因为 appDelegate 是一个易于自定义和访问的对象,以避免将模型传递给每个对象。

【讨论】:

我同意你的看法,一定是这种错误。我会查看我可能会发布它的代码并回来告诉你。有没有办法在应用程序运行时“跟踪”一个对象以了解它何时被释放? 你可以重写 release 方法,简单地调用 [super release] 然后在那里设置一个断点。 有些奇怪。如果我不执行“removeAllObjects”并且仍然执行 [dem release] ,则对象会继续添加到 tableview 中(x2、x3、x4 ......在视图的任何重新加载时)。但我仍然可以读取数组中的任何对象。我只是不能删除它们。 这是我的第一个应用程序,很抱歉造成混乱。什么样的优化? 我回来找你,因为我还没有解决我的问题。我在 appDelegate 中填写 tab_demandes。我可以从 appDelegate 方法中执行 removeAllObjects 但从另一个类中它不会起作用。

以上是关于向 MutableArray 添加或删除对象时泄漏的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中创建内存泄漏?

如何在 Java 中创建内存泄漏?

向 MKMapView 添加注释的最佳方法

如何根据objective-C中的标签号将按钮添加到MutableArray?

向控件添加自定义删除(后退、前移)按钮

jpa hibernate中扫描太多实体时,glassfish启动很慢或内存泄漏