views:

91

answers:

2

Hi guys,

i have a memory leak in my app. My app launches on a tableviewcontroller. i parse a json file to fill an array. Then this array is used to fill the tableview's cells. I fill my array with objects (class).

I do:

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

My array and tableview are filled at launch, no problem. if i hit a table cell and then want to come back on the tableview my app crash on :

[tab_Demandes removeAllObjects];

If i dont do [dem release] i have leaks in instruments every time i reload tab_Demandes. RemoveAllObjects works but i have leaks.

Thx for any help as usual.

Wallou ++

Edit : here is where i made my cells. Maybe i mess up when creating the cells Actually tab_Demandes is declared in the delegate with get/set to access it from other classes (where i load my 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;    

}

NEW EDIT:

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
A: 

I guess you should use [tab_Demandes addObject:[dem autorelease]]; instead of:

[tab_Demandes addObject:dem];
[dem release];

as stated here

dkk
it didnt work, still the same issue
wallou
the only difference that makes is that dem will be released at the end of the event loop instead of directly.
VdesmedT
ok i see ... thx
wallou
A: 

The code above is correct. I wondering if you don't over release objects that are in you array (i.e. during tableView:cellForRowAtIndexPath method). When calling removeAllObject, the method release every object it removes. If one object is already released and deallocated, you app will crash.

Proposed Optimization :

-Be sure that the cellIdentifier in the nib is well @"Cell"

-Replace

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

by

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

to avoid querying the array too much time.

-Avoid placing your model in the appDelegate and create a singleton model object instead. This is a common beginner design mistake driven by the fact that the appDelegate is an easy object to customize and access to avoid passing you model to every objects.

VdesmedT
i agree with you it has to be this kind of bug. I'll look in the code where i may release it and come back to tell you. Is there a way to "follow" an object while the app is running in order to know when it is released?
wallou
i edited my post to show how i create cells
wallou
You may override the release method an simply call [super release] then set a breakpoint there.
VdesmedT
there is something strange. if i don't do "removeAllObjects" and still do [dem release] , objects keep adding in the tableview (x2,x3,x4 ... at any reload of the view). BUT i still can read any objects in the array. i just cant delete them.
wallou
its my first app, sorry for the mess. what kind of optimization?
wallou
i come back at you because i havent solved my problem yet. i fill tab_demandes in the appDelegate. I can do removeAllObjects from appDelegate methods but from another class it won't work.
wallou
how have you declare the tab_Demandes property in the appDelegate (nonatomic, retain) ?
VdesmedT
i do: @property (nonatomic,retain) NSMutableArray *tab_Demandes; and @synthesize in the .m . Thx for the help, i saw you are from belgium. id
wallou
Nothing prevent us of doing so but it's clearly not fair ! Also, I suggest that we delete every comments that are not relevant to the question. So will I. (including this one as soon as you read it)
VdesmedT
i've just noticed something new [tab_Demandes removeAllObjects]; works within the appDelegate. tab_demandes has 0 objects but my app crashes right after, i dont know why yet. BUT when i do [[appDelegate tab_Demandes] removeAllObjects] in another class it crashes.
wallou
VdesmedT in fact the problem is that the dem attibutes are released in the dealloc method of the class. if i "comment" these releases i can do removeAllObjects. But i have then the attributes as leaked. It's the attributes/properties of the dem object that is the issue when i try to remove objects.
wallou
You really should read the Memory Management Document published by Apple. I'm sure that if you well respect those rules, everything will works fine. https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
VdesmedT