EDIT - added .h file
I'm having difficulty trying to find the cause of a double free error.
Steps taken to solve
1) Used the Zombies tool. Zombies reports that tid is being double freed
2) Set a breakpoint on malloc_error_break. This identifitied the following code segment as faulty:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[connection release];
[ldestination release];
[ldeparts_from release];
[ltime release];
[lcs_id release]; /// It breaks here
[carsharexml release];
}
3) I looked through the code to see where I had [lcs_id release] before - I found nothing.
4) In a desperate attempt to solve it I commented out [lcs_id release]. This stopped the
double free error messages but when I ran it through leaks it said that this was causing memory leaks.
What am I doing wrong?
Thanks very much.
Below is a complete copy of the code:
#import <UIKit/UIKit.h>
#import "MyManager.h"
#interface ListOfCarShares : UITableViewController <NSXMLParserDelegate>
{
NSURLConnection *connection;
NSMutableData *carsharexml;
NSMutableArray *ldestination;
NSMutableArray *ldeparts_from;
NSMutableArray *lcs_id;
NSMutableArray *ltime;
NSMutableString *currentElement;
NSMutableString *tdest;
NSMutableString *tfrom;
NSMutableString *ttime;
NSMutableString *tid;
}
-(void)fetchcarshares;
#property (nonatomic, assign) IBOutlet UITableViewCell *maincell;
#end
//
// ListOfCarShares.m
// Warwick_Culture
//
// Created by Me on 26/10/2011.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "ListOfCarShares.h"
#implementation ListOfCarShares
#synthesize maincell;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
currentElement = [[elementName copy] autorelease];
if ([elementName isEqualToString:#"destination"])
{
//NSLog(#"found current conditions tag it reads %#",currentElement);
tdest = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"departs_from"])
{
tfrom = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"time"])
{
ttime = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"cs_id"])
{
tid = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"destination"])
{
[tdest appendString:string];
}
if ([currentElement isEqualToString:#"departs_from"])
{
[tfrom appendString:string];
}
if ([currentElement isEqualToString:#"time"])
{
[ttime appendString:string];
}
if ([currentElement isEqualToString:#"cs_id"])
{
[tid appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([currentElement isEqualToString:#"destination"])
{
[ldestination addObject:tdest];
[tdest release];
}
if ([currentElement isEqualToString:#"departs_from"])
{
[ldeparts_from addObject:tfrom];
[tfrom release];
}
if ([currentElement isEqualToString:#"time"])
{
[ltime addObject:ttime];
[ttime release];
}
if ([currentElement isEqualToString:#"cs_id"])
{
[lcs_id addObject:tid];
[tid release];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
ldestination = [[NSMutableArray alloc] init];
ldeparts_from = [[NSMutableArray alloc] init];
ltime = [[NSMutableArray alloc] init];
lcs_id = [[NSMutableArray alloc] init];
carsharexml = [[NSMutableData alloc] init];
[self fetchcarshares];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[connection release];
[ldestination release];
[ldeparts_from release];
[ltime release];
[lcs_id release]; ///
[carsharexml release];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [ltime count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"carsharecell" owner:self options:nil];
}
// Configure the cell...
cell=maincell;
UILabel *from;
UILabel *dest;
UILabel *time;
from = (UILabel *)[cell viewWithTag:4];
dest = (UILabel *)[cell viewWithTag:5];
time = (UILabel *)[cell viewWithTag:6];
from.text=[ldeparts_from objectAtIndex:indexPath.row];
dest.text=[ldestination objectAtIndex:indexPath.row];
time.text=[ltime objectAtIndex:indexPath.row];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
-(void)fetchcarshares
{
MyManager *sharedManager = [MyManager sharedManager];
NSString *urlString = [NSString stringWithFormat:#"http://url/get.php?username=%#&password=%#",sharedManager.user,sharedManager.passw];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
-(void) connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
[carsharexml appendData:data];
}
-(void) connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *xmlcheck = [[NSString alloc] initWithData:carsharexml encoding:NSUTF8StringEncoding];
NSLog(#"%#",xmlcheck);
[xmlcheck release];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData: carsharexml];
[parser setDelegate:self];
[parser parse];
[parser release];
[[self tableView] reloadData];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 102;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
-(void)dealloc
{
[super dealloc];
}
#end
Try this....
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
ldestination = [[[NSMutableArray alloc] init]retain];
ldeparts_from = [[[NSMutableArray alloc] init]retain];
ltime = [[[NSMutableArray alloc] init]retain];
lcs_id = [[[NSMutableArray alloc] init]retain];
carsharexml = [[[NSMutableData alloc] init]retain];
[self fetchcarshares];
}
if lcs_id property not define as retain you need to replace the line
lcs_id = [[NSMutableArray alloc] init];
to
lcs_id = [[[NSMutableArray alloc] init] retain];
or another work around would be in
- (void)viewWillDisappear:(BOOL)animated
{
if(lcs_id)
{
[lcs_id release];
lcd_id = nil;
}
}
For the Crashing issue, please check below point
1. Please make sure you haven't use [autorelease] for object lcs_id
2. Most important, if you have use same variable in other pages in application, you have received above error.
please try
[this.lcs_id release]
Your error will resolved.
Related
I want to add a UISearchBarto the following code below, that I am using in Xcode 4.6.
Can someone please help me?
//
#import "SocialMasterViewController.h"
#import "SocialDetailViewController.h"
#interface SocialMasterViewController () {
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSString *element;
NSArray *filteredStrings;
}
#end
#implementation SocialMasterViewController
-(void)gotosharing {
UIStoryboard *sharingStoryboard = [UIStoryboard storyboardWithName:#"Sharing" bundle:nil];
UIViewController *initialSharingVC = [sharingStoryboard instantiateInitialViewController];
initialSharingVC.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentViewController:initialSharingVC animated:YES completion:nil];
}
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad {
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://www.rssmix.com/u/3735817/rss.xml"
];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
}
- (void)refresh:(UIRefreshControl *)refreshControl {
[refreshControl endRefreshing];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return feeds.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"title"];
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
element = elementName;
if ([element isEqualToString:#"item"]) {
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
} else if ([element isEqualToString:#"link"]) {
[link appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *string = [feeds[indexPath.row] objectForKey: #"link"];
[[segue destinationViewController] setUrl:string];
}
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self filterURLsWithSearchBar:searchText];
[self.tableView reloadData];
}
- (void)filterURLsWithSearchBar:(NSString *)searchText
{
//[filteredStrings removeAllObjects];
for (NSString *rssUrl in feeds)
{
NSComparisonResult result = [rssUrl compare:searchText
options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)
range:[rssUrl rangeOfString:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch)]];
if (result == NSOrderedSame) {
[self->feeds addObject:filteredStrings];
}
}
}
#end
Basically, I am want to filter the results of what is brought in by the NSXMLParser into search terms as they are typed into a search bar.
Any help is much appreciated from you guys/gals.
Do this
Store the value get from parser into an array. responseArray
Use another array to store the value to show in table
datasourceArray
After webvservice recieve successful response datasourceArray=responseArray then reload table with [tableView reloadData]
When search starts,search from responseArray load the result into DatasourceArray then call reloadData again
you can use textFeildDidBegunEditingdelegate method of uitextFeild
then this code will help you filter
NSMutableArray *array1=(NSMutableArray*)[txtEditFavoriteColor.text componentsSeparatedByString:#" "];//words from textFeild
for (NSString *str in array1)
{
NSString *tempStr = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if([tempStr length])
{
[arryOfWordsToBeSearched addObject:tempStr];
}
}
NSMutableArray *subpredicates = [NSMutableArray array];
for(NSString *term in arryOfWordsToBeSearched) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"name contains[cd] %#",term];
[subpredicates addObject:p];
}
NSPredicate *filter = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];
//***************************************************************predicate made above******
result = [[NSMutableArray alloc]initWithArray:[arryOfDummyData filteredArrayUsingPredicate: filter]];//search on data array using predicate
Create table view controller subclass with nibfile. Add search bar to nibfile at top of table view. Then search result view controller will be added automatically.
most of the property of searchResultViewController like delegate, searchBar ,searchDisplayDatasource and delegate are automatically set. and also for search bar delegate is set as file owner.
Now implement table view conform to this protocol . .
Implement the following delegate method .
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
// create the array of ur search result object
}
now implementing tableViewDataSource and delegate check which table is calling method
as follows
if (tableView == self.searchDisplayController.searchResultsTableView)
{
// searchResultsTableView
}
else
{
// main table view
}
implement the corresponding code.
I am newer in iPhone application development. I want to find out why tableview cell is not showing data. I tried a lot of ways. I am giving my code below.
Note that I am seeing data at my console which is coming from XML file but it's not displaying in UITableView cell.
#synthesize newsTable;
#synthesize activityIndicator;
#synthesize rssParser;
#synthesize stories;
#synthesize item;
#synthesize currentElement;
#synthesize currentTitle, currentDate, currentSummary, currentLink;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
#pragma mark -
#pragma mark Parsing
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([stories count] == 0) {
NSString * path = #"http://icms7.bitmascot.com:8080/webcommander2.0S2/rest/services/catalogue/getAllDummyCategoryProduct";
[self parseXMLFileAtURL:path];
}
cellSize = CGSizeMake([newsTable bounds].size.width, 60);
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
stories = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(#"found file and started parsing");
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"ProductData"])
{
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(#"ended element: %#", elementName);
if ([elementName isEqualToString:#"ProductData"])
{ // save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"id"];
[item setObject:currentLink forKey:#"productNumber"];
[item setObject:currentSummary forKey:#"name"];
[item setObject:currentDate forKey:#"dateCreated"];
[stories addObject:[item copy]];
NSLog(#"adding story: %#", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(#"found characters: %#", string);
// save the characters for the current item...
if ([currentElement isEqualToString:#"ProductData"])
{
[currentTitle appendString:string];
}
else if ([currentElement isEqualToString:#"id"])
{
[currentLink appendString:string];
}
else if ([currentElement isEqualToString:#"ProductNumber"])
{
[currentSummary appendString:string];
}
else if ([currentElement isEqualToString:#"dateCreatrd"])
{
[currentDate appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(#"all done!");
NSLog(#"stories array has %d items", [stories count]);
NSLog(#"data in stories: %#",[stories description]);
[newsTable reloadData];
}
#pragma mark tableView
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return [stories count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MyIdentifier];
}
// Set up the cell
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
//[cell setText:[[stories objectAtIndex: storyIndex] objectForKey: #"title"]];
//[cell setLabelText:[[stories objectAtIndex:storyIndex] objectForKey: #"ProductData"]];
//[cell setText:[stories objectAtIndex:storyIndex]];
cell.textLabel.text = [stories objectAtIndex:storyIndex];
NSLog(#"%# ",cell.textLabel.text);
//cell.detailTextLabel.text = [stories objectAtIndex:indexPath.row];
return cell;
}
/*
- (void)setLabelText:(NSString *)_text{
UILabel *cellText;
cellText.text= _text;
[cellText sizeToFit];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentTitle release];
[currentDate release];
[currentSummary release];
[currentLink release];
[super dealloc];
}
#end
Try to set value of property textLabel, not detailedTextLabel :
cell.textLabel.text = [[stories objectAtIndex:storyIndex] valueForKey:#"productNumber"];
Also try to create cell using predefined styles:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MyIdentifier];
To make a cell you should use
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
method. By default the detailTextLabel is not visible in the cell.
Try to use other styles - UITableViewCellStyleValue1, for example.
Instead of giving,
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
//[cell setText:[[stories objectAtIndex: storyIndex] objectForKey: #"title"]];
//[cell setLabelText:[[stories objectAtIndex:storyIndex] objectForKey: #"ProductData"]];
//[cell setText:[stories objectAtIndex:storyIndex]];
cell.detailTextLabel.text = [stories objectAtIndex:storyIndex];
try this code:
cell.detailTextLabel.text = [stories objectAtIndex:indexPath.row];
before that ,just check your array(stories)having content?
Thank You..
cell.detailTextLabel.text = [stories objectAtIndex:storyIndex];
replace above statement with belo wstatement iy will work i think
cell.detailTextLabel.text = [stories objectAtIndex:indexPath.row];
I have a question here: Confusing double free error message/memory leak in iPhone app which I think needs a new question to answer it.
The code I am interested in is in that question but I will re post it here
#import <UIKit/UIKit.h>
#import "MyManager.h"
#interface ListOfCarShares : UITableViewController <NSXMLParserDelegate>
{
NSURLConnection *connection;
NSMutableData *carsharexml;
NSMutableArray *ldestination;
NSMutableArray *ldeparts_from;
NSMutableArray *lcs_id;
NSMutableArray *ltime;
NSMutableString *currentElement;
NSMutableString *tdest;
NSMutableString *tfrom;
NSMutableString *ttime;
NSMutableString *tid;
}
-(void)fetchcarshares;
#property (nonatomic, assign) IBOutlet UITableViewCell *maincell;
#end
#import "ListOfCarShares.h"
#implementation ListOfCarShares
#synthesize maincell;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
currentElement = [[elementName copy] autorelease];
if ([elementName isEqualToString:#"destination"])
{
//NSLog(#"found current conditions tag it reads %#",currentElement);
tdest = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"departs_from"])
{
tfrom = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"time"])
{
ttime = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"cs_id"])
{
tid = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"destination"])
{
[tdest appendString:string];
}
if ([currentElement isEqualToString:#"departs_from"])
{
[tfrom appendString:string];
}
if ([currentElement isEqualToString:#"time"])
{
[ttime appendString:string];
}
if ([currentElement isEqualToString:#"cs_id"])
{
[tid appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([currentElement isEqualToString:#"destination"])
{
[ldestination addObject:tdest];
[tdest release];
}
if ([currentElement isEqualToString:#"departs_from"])
{
[ldeparts_from addObject:tfrom];
[tfrom release];
}
if ([currentElement isEqualToString:#"time"])
{
[ltime addObject:ttime];
[ttime release];
}
if ([currentElement isEqualToString:#"cs_id"])
{
[lcs_id addObject:tid];
[tid release];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
ldestination = [[NSMutableArray alloc] init];
ldeparts_from = [[NSMutableArray alloc] init];
ltime = [[NSMutableArray alloc] init];
lcs_id = [[NSMutableArray alloc] init];
carsharexml = [[NSMutableData alloc] init];
[self fetchcarshares];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[connection release];
[ldestination release];
[ldeparts_from release];
[ltime release];
[lcs_id release]; ///
[carsharexml release];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [ltime count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil)
{
[[NSBundle mainBundle] loadNibNamed:#"carsharecell" owner:self options:nil];
}
// Configure the cell...
cell=maincell;
UILabel *from;
UILabel *dest;
UILabel *time;
from = (UILabel *)[cell viewWithTag:4];
dest = (UILabel *)[cell viewWithTag:5];
time = (UILabel *)[cell viewWithTag:6];
from.text=[ldeparts_from objectAtIndex:indexPath.row];
dest.text=[ldestination objectAtIndex:indexPath.row];
time.text=[ltime objectAtIndex:indexPath.row];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
-(void)fetchcarshares
{
MyManager *sharedManager = [MyManager sharedManager];
NSString *urlString = [NSString stringWithFormat:#"http://url/get.php?username=%#&password=%#",sharedManager.user,sharedManager.passw];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
-(void) connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
[carsharexml appendData:data];
}
-(void) connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *xmlcheck = [[NSString alloc] initWithData:carsharexml encoding:NSUTF8StringEncoding];
NSLog(#"%#",xmlcheck);
[xmlcheck release];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData: carsharexml];
[parser setDelegate:self];
[parser parse];
[parser release];
[[self tableView] reloadData];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 102;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
-(void)dealloc
{
[super dealloc];
}
#end
I only have one property defined in the .h file. The people who answered that question seem to think that the reason I am having double free error is due to the fact I don't have #property for my variables.
I have lots of code practically identical to this and I don't have a problem.
My questions are
When should I use a property?
Should I be using properties here and why?
Thanks
You technically only need to use properties for values that are intended to be accessible from other classes, but many find it easier to use (retained) properties for all pointer-type instance variables so that the retaining is a bit more automatic. (And then use self.propertyName = xxx; notation for setting and self.propertyName = nil; for releasing in dealloc.)
Yes, you can do the retains and releases "manually", but it's a hair tedious to do so, and you tend to muck things up when you make "quick edits". The one thing you have to watch out for, though, is assigning a retained (not simply autoretained) value (such as your alloc/init values) to a self.xxx property. This will result in double retain, if you don't mitigate it somehow.
Another thing to do, if you don't use properties, is to always nil a pointer value after you release it. This prevents you from accidentally using the released value and and it prevents you from doing a double release.
(Note that it's in no way "bad programming" to use "lazy" techniques like I described above, vs "perfectly" figuring out everything. About 98% of programming is debugging, and anything you can do to prevent bugs or make them easier to find is goodness.)
(I'll also note that your problem in the above code appears to be mainly that you do not nil thetdest et al pointers after releasing them. And your if tests should likely check to see if the pointer has been nilled before using it.)
Added: Note that the above applies to pre-ARC programs. With ARC the "rules" change substantially.
Properties do a lot of things. At the most superficial level, they let you access your member variables in dotted form. At best, they can be excellent memory management tools (and more).
Let's say you have a variable:
NSNumber * myNumber;
Later in the code, you access it as:
myNumber = [NSNumber numberWithInt: 5];
The problem is that you might lose reference to the previously stored value in myNumber. Possible Memory Leak!! At this point, you don't have a retain on myNumber and it may get dealloc'd before you're done using it.
How can properties help? Let's say you defined a property around it and used synthesize:
In the interface definition:
NSNumber * myNumber;
...
#property (retain, nonatomic) NSNumber * myNumber;
and
In the implementation file:
#synthesize myNumber;
This will create a getter and setter. Meaning... everytime you assign myNumber to something as in:
self.myNumber = newNumber;
the following setter method (created by synthesize directive) gets invoked:
- (NSNumber *) setMyNumber: (NSNumber *) newNumber {
[myNumber release];
myNumber = newNumber;
[myNumber retain];
return newNumber;
}
Here, myNumber gets a retain automatically. This is very tedious to do by hand everytime... as you can see, it's much easier to use properties.
This is still not a perfect solution, though! Why? What if you use the following statement in your implementation:
myNumber = newNumber;
Remember, properties' getter and setter get invoked only if you're using the dotted notation (self.myNumber). So here, using properties has done nothing for us, 'cause we forgot to use them!
This is very common and likely lapse and understandingly frustrating.
So, what's the best way? This is what I recommend (as do countless others):
In the interface class:
NSNumber * _myNumber;
...
#property (retain, nonatomic) NSNumber * myNumber;
In the implementation file:
#synthesize myNumber = _myNumber;
Now, you can access your-number as:
self.myNumber = whateverNewNumber;
But, if you did:
myNumber = whateverNewNumber;
You'll get an error... because myNumber variable just doesn't exist... forcing you to use self.myNumber everytime!
Also, if you do choose to go this route, don't forget the dealloc:
- (void) dealloc {
[_myNumber release];
_myNumber = nil;
}
or more succinct:
- (void) dealloc {
self.myNumber = nil;
}
I am making an app with a tab bar and one of the tabs is an rss reader, the app works, but I can't figure out how to display the selected article content in a UIWebview. everything works right now except upon selecting a cell it pushes to DetailViewController.xib which has a UIWebView in it. But I have it set up so the code finds the URL of the article automatically I just can't figure out how to display it in the UIWebView. Also relatively an Objective-C noob
#import "RSSTableViewController.h"
#import "OCVMobileAppDelegate.h"
#import "DetailViewController.h"
#implementation RSSTableViewController
#synthesize detailView;
#pragma mark -
#pragma mark Initialization
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
self = [super initWithStyle:style];
if (self) {
// Custom initialization.
}
return self;
}
*/
#pragma mark -
#pragma mark View lifecycle
/*
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
*/
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([stories count] == 0) {
NSString * path = #"http://feeds.feedburner.com/TheAppleBlog";
[self parseXMLFileAtURL:path];
}
cellSize = CGSizeMake([newsTable bounds].size.width, 60);
}
- (void)parseXMLFileAtURL:(NSString *)URL {
stories = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser {
NSLog(#"found file and started parsing");
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i )", [parseError code]];
NSLog(#"error parsing XML: %#", errorString);
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//NSLog(#"ended element: %#", elementName);
if ([elementName isEqualToString:#"item"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentLink forKey:#"link"];
[item setObject:currentSummary forKey:#"summary"];
[item setObject:currentDate forKey:#"date"];
[stories addObject:[item copy]];
NSLog(#"adding story: %#", currentTitle);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//NSLog(#"found characters: %#", string);
// save the characters for the current item...
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:#"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
NSLog(#"all done!");
NSLog(#"stories array has %d items", [stories count]);
[newsTable reloadData];
}
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [stories count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// Configure the cell...
int storyindex = [indexPath indexAtPosition:[indexPath length]-1];
[cell setText:[[stories objectAtIndex:storyindex]objectForKey:#"title"]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: #"link"];
// clean up the link - get rid of spaces, returns, and tabs...
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#"\n" withString:#""];
storyLink = [storyLink stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"link: %#", storyLink);
if(indexPath.row==0)
{
DetailViewController *newviewController=[[[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil]autorelease];
[self.navigationController pushViewController:newviewController animated:YES];
}
else {
DetailViewController *newviewController=[[[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil]autorelease];
[self.navigationController pushViewController:newviewController animated:YES];
}
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentTitle release];
[currentDate release];
[currentSummary release];
[currentLink release];
[super dealloc];
}
#end
NSString *requestURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:storyLink] encoding:NSUTF8StringEncoding error:nil];
[newviewcontroller.mywebview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:requestURL]]];
(replace mywebview with your own webview name)
Would this do?
I will eventually get hold of this memory allocation idea and iphone development but i am struggling. Below is my code of my NSXMLParser for a twitter viewer i have made. It works fine and doesn't leak until about 30secs after the code is loaded... Its frustrating me because as soon as i get this parser done and without leaks I will be ready to go :).
I've watched loads of video tutorials and just need a help looking through my own code so i can get an idea.
rssParser.m
//
// rssParser.m
// template
//
// Created by Jonathan Pink on 17/08/2011.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "rssParser.h"
#implementation rssParser
#synthesize entries;
-(id)loadXMLData:(NSData *)xml{
entries = [[NSMutableArray alloc] init];
xmlParser = [[NSXMLParser alloc] initWithData:xml];
[xmlParser setDelegate:self];
[xmlParser parse];
return self;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
[currentElement release];
currentElement = [elementName copy];
if([elementName isEqualToString:#"item"])
{
RssData = [[rssData alloc] init];
currentRssDescription = [[NSMutableString alloc] init];
currentRssLink = [[NSMutableString alloc] init];
currentRssPubDate = [[NSMutableString alloc] init];
currentRssTitle = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:#"item"])
{
RssData.rssLink = currentRssLink;
RssData.rssDescription = currentRssDescription;
RssData.rssPubDate = currentRssPubDate;
RssData.rssTitle = currentRssTitle;
NSLog(#"currenttitle = %#",RssData.rssTitle);
}
if([elementName isEqualToString:#"item"])
{
[entries addObject:RssData];
RssData = nil;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if([currentElement isEqualToString:#"title"])
{
[currentRssTitle appendString:string];
}
else if([currentElement isEqualToString:#"link"])
{
[currentRssLink appendString:string];
}
else if([currentElement isEqualToString:#"description"])
{
[currentRssDescription appendString:string];
}
else if([currentElement isEqualToString:#"pubDate"])
{
[currentRssPubDate appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(#"all done!");
NSLog(#"stories array has %d items", [entries count]);
}
-(void)dealloc{
[currentElement release];
[currentRssDescription release];
[currentRssLink release];
[currentRssPubDate release];
[currentRssTitle release];
[xmlParser release];
[RssData release];
[entries release];
[super dealloc];
}
#end
and the twitter view controller
//
// TwitterViewController.m
// template
//
// Created by Jonathan Pink on 16/08/2011.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "TwitterViewController.h"
#import "ASIHTTPRequest.h"
#implementation TwitterViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[config release];
[RssParser release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(ProcessAndParse)];
self.navigationItem.rightBarButtonItem = anotherButton;
[anotherButton release];
numberOfTextRows = 4;
config = [[Configuration alloc] init];
[super viewDidLoad];
[self ProcessAndParse];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
-(void)ProcessAndParse{
NSURL *url = [config urlForFeed:#"Twitter"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
RssParser = [[rssParser alloc] loadXMLData:responseData];
[self.tableView reloadData];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([RssParser entries] == 0) {
return 1;
}
else
{
return [[RssParser entries]count];
}
}
/*#define FIXED_HEIGHT_SECTION 18
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//RSSData *currentEntry = [[rssParser rssEntries] objectAtIndex:indexPath.row];
CGSize theSize = [[currentEntry rssDescription] sizeWithFont:[UIFont systemFontOfSize:12.0f] constrainedToSize:CGSizeMake(265.0f, 9999.0f) lineBreakMode:UILineBreakModeWordWrap];
// This gets the size of the rectangle needed to draw a multi-line string
numberOfTextRows = round(theSize.height / 18);
// 18 is the size of the font used in the text label
// This will give us the number of lines in the multi-line string
if ((indexPath.section == FIXED_HEIGHT_SECTION) || (numberOfTextRows < 2)) {
return 44;
// 44 is the default row height; use it for empty or one-line cells (or in other table sections)
} else {
return theSize.height + 35;
// 16 seems to provide a decent space above/below; tweak to taste
}
}*/
- (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];
}
rssData *currententry =[[RssParser entries] objectAtIndex:indexPath.row];
if ([RssParser entries] == 0) {
cell.textLabel.text = #"No Records";
}
else
{
cell.textLabel.text = [currententry rssTitle];
}
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
#end
Any help i will be eternally grateful! :)
Did you try to profile your app with Instruments?
If you use the analyzation for memory leaks properly it will directly tell you where in the code the memory leak is caused.
This line looks a bit suspect
[entries addObject:RssData];
RssData = nil;
You are nullifying the pointer but not releasing what it is pointing to. Your code is fairly hard to follow because you are not following some standard conventions.
Your init method is not safe and it should start with init...
Try:
-(id)initWithXMLData:(NSData *)xml
{
self = [super init];
if (self) {
entries = [[NSMutableArray alloc] init];
xmlParser = [[NSXMLParser alloc] initWithData:xml];
[xmlParser setDelegate:self];
[xmlParser parse];
}
return self;
}
For naming things
RssData // Class names should start with uppercase
rssData // variables and ivars should start with lowercase
Otherwise it's hard to tell when you are working with a class or an instance of a class.
You should also look at using properties which would remove much of the complication of manual memory management.