I am facing a simple yet annoying problem of memory deallocation and message sending to a freed object.
I am trying to get Rss feed from a web page. I developed the applet in 2 stages, in stage one , as i am yet new to iphone development i tried gettin开发者_开发百科g the text part of an Rss feed from a webpage with success and no problems. In stage 2 i tried getting the links to images and presenting them both on each UITableViewCell and the detailed view afterwards.
i have a class that loads the rss and is responsible for the parsing and the returning of the mutable array which i return through [array copy]
. everything works well, even though it takes some time to load. When i Run the app and try to scroll the table view i get a crash and an NSZombie message :
objc[37372]: FREED(id): message retain sent to freed object=0x3930cd0
and this happens also when i try to load the detailViewController without scrolling i post some of the tableViewController to see what is wrong.
- (void)viewDidLoad {
[super viewDidLoad];
post = [[Posts alloc]init];
//self.tableView.rowHeight = 160.0;
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.tintColor = [UIColor purpleColor];
NSLog(@"parser is about to init");
parser = [[XmlParser alloc] init];
array = [parser initWithURL:@"http://backend.deviantart.com/rss.xml?q=boost%3Apopular+meta%3Aall+max_age%3A8h&type=deviation&offset=0"];
//array = [parser initWithURL:@"http://www.enet.gr/rss?i=news.el.categories&c=politikh"];
NSLog(@"posts has %d items",[array count]);
[parser release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
post = [array objectAtIndex:indexPath.row];
// Set up the cell...
[cell.textLabel text:[post itemTitle]];
[cell.detailTextLabel setText:[post itemBody]];
[cell.imageView setImage:[self.post itemthumbnail]];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.
FirstDetailedViewController *anotherViewController = [[[FirstDetailedViewController alloc] initWithNibName:@"FirstDetailedViewController" bundle:nil]autorelease];
NSLog(@"posts count : %d", [array count]);
post = [array objectAtIndex:indexPath.row];
anotherViewController.currpost = [post retain];
[self.navigationController pushViewController:anotherViewController animated:YES];
}
The post clash is some NSMutableStrings and UIImages, all of them are allocated and initialized in their own init and dealloced in their own dealloc method. I am also having problem when i try to tap on a cell without scrolling but that's tommorows problem.
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
post = [array objectAtIndex:indexPath.row];
// Set up the cell...
[cell.textLabel text:[post itemTitle]];
[cell.detailTextLabel setText:[post itemBody]];
[cell.imageView setImage:[self.post itemthumbnail]];
}
return cell;}
You don't wan't to configure each cell for display at this place in the code. Your code should look something like this:
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
post = [array objectAtIndex:indexPath.row];
// Set up the cell...
[cell.textLabel text:[post itemTitle]];
[cell.detailTextLabel setText:[post itemBody]];
[cell.imageView setImage:[self.post itemthumbnail]];
return cell;
}
Solved it! simple init problem
Previous :
-(id)init
{
[super init];
channelTitle = [[NSMutableString alloc]init];
channelLink = [[NSMutableString alloc]init];
channelDescription = [[NSMutableString alloc]init];
channelPubDate = [[NSMutableString alloc]init];
itemTitle = [[NSMutableString alloc]init];
itemBody = [[NSMutableString alloc]init];
itemPubDate = [[NSMutableString alloc]init];
itemLink = [[NSMutableString alloc]init];
itemthumbnail = [[UIImage alloc]init];
itemthumbnailLink = [[NSString alloc]init];
itemImage = [[UIImage alloc]init];
itemImageLink = [[NSString alloc]init];
return self;
}
Now :
-(id)init
{
if (self==[super init]){
channelTitle = [[NSMutableString alloc]init];
channelLink = [[NSMutableString alloc]init];
channelDescription = [[NSMutableString alloc]init];
channelPubDate = [[NSMutableString alloc]init];
itemTitle = [[NSMutableString alloc]init];
itemBody = [[NSMutableString alloc]init];
itemPubDate = [[NSMutableString alloc]init];
itemLink = [[NSMutableString alloc]init];
itemthumbnail = [[UIImage alloc]init];
itemthumbnailLink = [[NSString alloc]init];
itemImage = [[UIImage alloc]init];
itemImageLink = [[NSString alloc]init];
}
return self;
}
the actual image was never allocated! now it is! :D
Most likely a problem with your data source being auto-released prematurely. Try and retain the array
object or declare a (retain) property for it and in your viewDidLoad
method:
NSArray *tmpArray = [parser initWithURL:@"http://backend.deviantart.com/rss.xml?q=boost%3Apopular+meta%3Aall+max_age%3A8h&type=deviation&offset=0"];
self.array = tmpArray;
Hope if helps. Rog
精彩评论