Hi all,
I have just started learning Objective-C, and I'm having a memory management issue. I believe I know which line of code caused the problem (as the program worked before I changed this line)...I just don't know why it failed.
The basic overview of this program is that I am attempting to write a class which will eventually have a few
UITableView's in it. Each table will be grouped into sections (and then obviously each of those sections has it's own cells). I wrote my own table and section class to store the data (and subclassed those for specific tables). Initially I have an
NSArray of
UITableViewCell's in each of the sections to represent the cells in that section. I intend to change that and write my own class for the cells (and initialise the
UITableViewCell's on the fly)...but something has gone wrong in the creation of these cells. I really would like to work out what has gone wrong before I change it, as there is something wrong my understanding of memory management as I thought it
should have worked (and somewhere between the manual memory management, the loose typing, and the vague compiler messages...I'm kinda worried that this is one of those languages where 'a little knowledge is a dangerous thing'
:p ).
For clarity's sake I'll try to go straight to the line I think is causing the problem (and then some context beneath it)...The gist of this is that I'm in my section class, in a helper method which initalises a cell and returns it to be added to an
NSArray of
UITableViewCells. The
NSArray cells is a property of the section object and is set as (retain, nonatomic). The problem is with the initialisation of the icon image for the cell...
I started off with the following which
did work:
NSString *imageFile = [[NSBundle mainBundle] pathForResource:imagePath ofType:@\"png\"];
cell.imageView.image = [[UIImage alloc] initWithContentsOfFile:imageFile];
Using the above code the cells initialised and the images displayed in the table without a problem.
And then I was reading a book and I saw a convenience method of the
UIImage class called
imageNamed which I thought would make these two lines neater, and so I tried to implement it instead of the above two lines:
cell.imageView.image = [UIImage imageNamed:@\"image1.png\"];
This failed with an
EXC_BAD_ACCESS error. I thought the NSArray would take 'ownership' of of the cell (and hence cell image)...but I had also read that class convenience methods have ownership over the objects they create and that you needed to take ownership with the retain keyword, so I tried:
cell.imageView.image = [[UIImage imageNamed:@\"image1.png\"] retain];
This also failed with an
EXC_BAD_ACCESS error. The image seems to be released before it should be (or something like that). I'm confused about how to handle the memory management here...I thought the couple of lines that worked would be roughly equivalent to the last line of code I posted :confused: . I could just change it back to the lines of code that actually worked but I'm more concerned about why it failed as I'm sure I'll hit a problem like this again.
I did also run NSZombies and got the error:
*** -[CFArray release]: message sent to deallocated instance 0x4b68900
So, something to do with the cells in the array (the only array in the program is the cells array).
Here is the context:
Table:
#import <Foundation/Foundation.h>
@interface Table : NSObject {
NSArray *sections;
}
@property (retain, nonatomic) NSArray *sections;
-(id) init;
@end
TableSection:
#import <Foundation/Foundation.h>
#import \"AppSettings.h\"
@interface TableSection : NSObject {
NSString *heading;
NSArray *cells;
NSString *cellIdentifier;
UITableViewCellAccessoryType cellAccessory;
UITableViewCellStyle cellStyle;
}
@property (retain, nonatomic) NSString *heading;
@property (retain, nonatomic) NSArray *cells;
@property (retain, nonatomic) NSString *cellIdentifier;
@property UITableViewCellAccessoryType cellAccessory;
@property UITableViewCellStyle cellStyle;
-(id) init;
-(void) dealloc;
-(UITableViewCell *) createCell:(NSString *)label pathForImage:(NSString *)imagePath;
@end
And the implementation of the
TableSection class:
#import \"TableSection.h\"
@implementation TableSection
@synthesize heading, cells, cellIdentifier, cellAccessory, cellStyle;
...
-(UITableViewCell *) createCell:(NSString *)label
pathForImage:(NSString *)imagePath
{
UITableViewCell *cell = [[UITableViewCell alloc]
initWithStyle:cellStyle
reuseIdentifier:cellIdentifier];
cell.textLabel.text = label;
cell.textLabel.font = [[AppSettings instance] labelFont];
//NSString *imageFile = [[NSBundle mainBundle] pathForResource:imagePath ofType:@\"png\"];
//cell.imageView.image = [[UIImage alloc] initWithContentsOfFile:imageFile];
cell.imageView.image = [[UIImage imageNamed:@\"image1.png\"] retain];
return cell;
}
...
@end
And the
createCell method is being called in a subclass of the
TableSection class in the subclasses
init method like this:
-(id) init
{
self = [super init];
if (self) {
heading = @\"Section heading:\";
UITableViewCell *cell1 = [super createCell:@\"Cell 1\" pathForImage:@\"image1\"];
UITableViewCell *cell2 = [super createCell:@\"Cell 2\" pathForImage:@\"image2\"];
UITableViewCell *cell3 = [super createCell:@\"Cell 3\" pathForImage:@\"image3\"];
cells = [[NSArray alloc] initWithObjects:cell1, cell2, cell3, nil];
}
return self;
}
Can anyone help?
Replies
Leak:
Leak:
This is ok by itself, but depends on what you do with the returned object:
... but you do indeed leak the returned object here:
None of these are related to your crash. You are most likely over-releasing something somewhere.
The whole approach here is really odd. There is very little reason to put cells in your own array. This largely defeats the caching mechanism that table views have.
SlickShopper 2 | BTIConcepts on GitHub | Free NSLog utility | Free Getter Utility | Leave a PayPal donation.
Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | A Model (Object) Is A Beautiful Thing
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeOn the second point, yes...the approach/design is very odd and very awkward...it needs redoing...I'm still trying to work out how to adjust to the language features. Back off to the books, I think...
Cheers.
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome