向 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 添加或删除对象时泄漏的主要内容,如果未能解决你的问题,请参考以下文章