Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 01-03-2009, 06:12 PM   #1 (permalink)
New Member
 
Join Date: Jul 2008
Posts: 31
pendraggon87 is an unknown quantity at this point
Default EXEC_BAD_ACCESS help

So heres the deal: I am creating an exchange rate application. It pulls information from an xml file, and it gets all the information, puts it in an NSDictionary. This then gets stored in the preferences by using NSUserDefaults. It is set so that it updates once a day, and when it updates writes in the update time in the preferences.

In the table view controller, for some reason, there is an error and the problem i believe is that somehow the rates array has been released or something - because when I try to examine it nothing shows up, and it crashes when trying to output it to a log file.

AppDelegate:
Code:
//
//  ExchangeRater_2AppDelegate.m
//  ExchangeRater_2
//
//  Created by Aaron Katz on 1/2/09.
//  Copyright __MyCompanyName__ 2009. All rights reserved.
//

#import "ExchangeRater_2AppDelegate.h"
#import "RootViewController.h"
#import "XMLParser.h"

#define EURO_RATE_XML_URL @"http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"

@implementation ExchangeRater_2AppDelegate
@synthesize window;
@synthesize rootViewController;
@synthesize rates;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
	//Why this warning?
    [rootViewController.mainViewController setActivityAnimation:AIStart];
	[self loadPreferences]; //Load preferences on launch.
	
	[window addSubview:[rootViewController view]];
    [window makeKeyAndVisible];
}

-(void)loadPreferences {
	NSUserDefaults *defaults = [[NSUserDefaults standardUserDefaults] retain];
	if([defaults objectForKey:@"ExchangeRatesLastUpdated"]==nil){
		//There is no data stored.
		[self setDefaultPrefs];
		
	}
	else {
		NSDate *today = [NSDate dateWithNaturalLanguageString:@"today at 00:00 +0000"];
		NSDate *updated = (NSDate *)[defaults objectForKey:@"ExchangeRatesLastUpdated"];
		if([updated earlierDate:today]&&[updated isEqualToDate:today]==NO){
			//Need to update
			NSLog(@"Need to update");
			self.rates = [defaults objectForKey:@"ExchangeRateDict"];
			[self updateRates];
		}
		else {
			NSLog(@"Up to date");
			self.rates = [defaults objectForKey:@"ExchangeRateDict"];
		}
		[rootViewController insertTable];
	}
	[rootViewController.mainViewController setActivityAnimation:AIStop];
}

-(void)setDefaultPrefs{
	NSUserDefaults *prefs = [[NSUserDefaults standardUserDefaults] retain];
	//Set the base currency to Euro.
	[prefs setObject:@"EUR" forKey:@"ExchangeRatesBaseCurrCode"];
	[prefs setObject:nil forKey:@"ExchangeRatesLastUpdated"];
	[prefs setObject:nil forKey:@"ExchangeRateDict"];
	
	//Attempt tp update the preferences.
	[self updateRates];
}

-(void)updateRates {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSError *parseError;
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	XMLParser *parser = [[XMLParser alloc] init];
	[parser parseXMLFileAtURL:[NSURL URLWithString:EURO_RATE_XML_URL] parseError:&parseError del:self theRates:rates];
	[parser release];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	[pool release];
	[rootViewController.mainViewController setActivityAnimation:AIStop];
}
	
-(void)commitParseResults:(NSValue *)val {
	TempCurrencyItem tci;
	[val getValue:&tci];
	NSString *changeStr;
	changeStr = @"";
	//NO rates have been saved.
	if(rates==nil) {
		rates = [[NSArray alloc] init];
	}
	
	//@TODO: Change amount.
	NSNumber *rate = [NSNumber numberWithFloat:tci.rate];
	NSString *currencyCode = tci.currencyCode;
	NSString *time = tci.time;
	NSArray *values = [NSArray arrayWithObjects:changeStr,currencyCode,rate,[NSNumber numberWithInt:CDNull],time,nil];
	NSArray *keys = [NSArray arrayWithObjects:@"ChangeAmount",@"CurrencyCode",@"Rate",@"Direction",@"LastUpdated",nil];
	NSDictionary *tempDict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
	NSMutableArray *tempArray = [NSMutableArray arrayWithArray:rates];
	[tempArray addObject:tempDict];
	rates = [NSArray arrayWithArray:tempArray];
	[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:tempArray] forKey:@"ExchangeRateDict"];
}

-(void)setUpdateTime:(id)object {
	[[NSUserDefaults standardUserDefaults] setObject:[NSDate dateWithNaturalLanguageString:@"today at 00:00 +0000"] forKey:@"ExchangeRatesLastUpdated"];
}

- (void)dealloc {
	[rates release];
    [rootViewController release];
    [window release];
    [super dealloc];
}

@end

MainViewController

//
//  MainViewController.m
//  ExchangeRater_2
//
//  Created by Aaron Katz on 1/2/09.
//  Copyright __MyCompanyName__ 2009. All rights reserved.
//

#import "MainViewController.h"
#import "MainView.h"
#import "CurrencyCell.h"

@implementation MainViewController
@synthesize tableView;
@synthesize activityIndicator;

#pragma mark custom methods.
-(void)setActivityAnimation:(ActivityAnimationState)state{
	if(state==AIStart) [activityIndicator startAnimating];
	else if(state==AIStop) [activityIndicator stopAnimating];
}

#pragma mark Delegate Methods
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}

-(void)viewDidLoad{
	//Make the background color of the table view seamless.
	tableView.backgroundColor = [UIColor colorWithRed:25.1 green:25.1 blue:25.1 alpha:0];
	[super viewDidLoad];
}


/* Allow this!
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


- (void)dealloc {
	//Not sure what should be here
	[activityIndicator release];
	[tableView release];
    [super dealloc];
}


#pragma mark UITableViewDelegate and UITableViewDataSource methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	ExchangeRater_2AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
	return [appDelegate.rates count];
}

- (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
	
	ExchangeRater_2AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
	NSDictionary *rateDict = [appDelegate.rates objectAtIndex:indexPath.row];
	
	UIViewController *controller = [[UIViewController alloc] initWithNibName:@"CurrencyCell" bundle:nil];
	CurrencyCell *testCell = (CurrencyCell *)controller.view;
	[testCell.currencyCode setText:[rateDict objectForKey:@"CurrencyCode"]];
	NSString *newRateStr = [rateDict objectForKey:@"Rate"];
	float newRate = [newRateStr floatValue];
	[testCell.rate setText:[NSString stringWithFormat:@"%.2f", newRate]];
	NSString *direction = [rateDict valueForKey:@"Direction"];
	UIView *accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 30)];
	UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 45, 30)];
	label.backgroundColor = [UIColor clearColor];
	[label setText:[rateDict objectForKey:@"ChangeAmount"]];
	if([direction isEqualTo:[NSNumber numberWithInt:CDDown]]){
		//Rate dropped - show red background image and a minus sign.
		UIImage *img = [UIImage imageNamed:@"ChangeDown.gif"];
		UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
		[label setEnabled:YES];
		[accessoryView addSubview:imageView];
		
	}
	else if([direction isEqualTo:[NSNumber numberWithInt:CDUp]]){
		//Rate increased - show green background image and a plus sign.
		UIImage *img = [UIImage imageNamed:@"ChangeUp.gif"];
		UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
		[label setEnabled:YES];
		[accessoryView addSubview:imageView];
	}
	else if([direction isEqualTo:[NSNumber numberWithInt:CDNull]]){
		//No change - show disabled?
		//[label setText:[rateDict objectForKey:@"ChangeAmount"]];
		[label setEnabled:NO];
	}
	[accessoryView addSubview:label];
	testCell.accessoryView = accessoryView;
	
	cell = testCell;
	return cell;
}
@end
Thanks!
pendraggon87 is offline   Reply With Quote
Old 01-03-2009, 07:53 PM   #2 (permalink)
Registered Member
 
Join Date: Dec 2008
Posts: 31
mikep is on a distinguished road
Default

If you post the debug output from the console it would be easier to figure out where the problem is. I did not go through your code, but....

I would say, ya, it is being released and you are trying to access it after that.

Just for the fun of it, add a retain to see if that's the case. My guess would be some method is calling release on it. You would have to go through the docs and see which one. And call retain before it if you want to keep it around.
mikep is offline   Reply With Quote
Old 01-03-2009, 07:59 PM   #3 (permalink)
Registered Member
 
Stevenup7002's Avatar
 
Join Date: Nov 2008
Location: Ireland
Posts: 65
Stevenup7002 is on a distinguished road
Send a message via MSN to Stevenup7002 Send a message via Yahoo to Stevenup7002
Default

Yeah, there should be more information available in the debug console, which you can access by going to Run>Console.
Stevenup7002 is offline   Reply With Quote
Old 01-04-2009, 02:15 AM   #4 (permalink)
New Member
 
Join Date: Jul 2008
Posts: 31
pendraggon87 is an unknown quantity at this point
Default

How would I call retain on it? And here is the debug code. I often have trouble debugging because I do not know assembly. The console gives me nothing, just says loading into gdb. Here is the stack trace:

#0 0x9335d68c in objc_msgSend
#1 0x00003193 in -[MainViewController tableView:numberOfRowsInSection:] at MainViewController.m:68
#2 0x30becc8c in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
#3 0x30befa81 in -[UITableViewRowData rectForFooterInSection:]
#4 0x30bef70a in -[UITableViewRowData heightForTable]
#5 0x30aaedc1 in -[UITableView(_UITableViewPrivate) _updateContentSize]
#6 0x30aa1897 in -[UITableView noteNumberOfRowsChanged]
#7 0x30aa65eb in -[UITableView reloadData]
#8 0x30aa4585 in -[UITableView layoutSubviews]
#9 0x31e87278 in -[CALayer layoutSublayers]
#10 0x31e871a8 in CALayerLayoutIfNeeded
#11 0x31e86b30 in CAContextCommitTransaction
#12 0x31e86853 in CATransactionCommit
#13 0x903a19a2 in __CFRunLoopDoObservers
#14 0x903a3404 in CFRunLoopRunSpecific
#15 0x903a3cd8 in CFRunLoopRunInMode
#16 0x31699d38 in GSEventRunModal
#17 0x31699dfd in GSEventRun
#18 0x30a5dadb in -[UIApplication _run]
#19 0x30a68ce4 in UIApplicationMain
#20 0x00002398 in main at main.m:14
pendraggon87 is offline   Reply With Quote
Old 01-04-2009, 08:07 AM   #5 (permalink)
Registered Member
 
Join Date: Dec 2008
Posts: 31
mikep is on a distinguished road
Default

To call retain on a object is simply: [myObject retain];

But you want to figure out why. If you just call retain without a release somewhere, you will be creating a memory leak.

Quickly looking.. it looks like rates is the culprit. Either the object is not being created or it is being released.

Last edited by mikep; 01-04-2009 at 08:11 AM.
mikep is offline   Reply With Quote
Old 01-04-2009, 08:54 AM   #6 (permalink)
New Member
 
Join Date: Jul 2008
Posts: 31
pendraggon87 is an unknown quantity at this point
Default

Quote:
Originally Posted by mikep View Post
To call retain on a object is simply: [myObject retain];

But you want to figure out why. If you just call retain without a release somewhere, you will be creating a memory leak.

Quickly looking.. it looks like rates is the culprit. Either the object is not being created or it is being released.
I have had it work on the first ever run, and after that have been getting errors. How would I force rates to be retained. Or should I place it in another method other than applicationDidFinishLaunching.

the code that is triggering the error simply references rates:

Code:
ExchangeRater_2AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
return [appDelegate.rates count];
pendraggon87 is offline   Reply With Quote
Old 01-04-2009, 01:12 PM   #7 (permalink)
Registered Member
 
Join Date: Dec 2008
Posts: 31
mikep is on a distinguished road
Default

What happens if you do just "[rates count];"?

Last edited by mikep; 01-04-2009 at 01:15 PM.
mikep is offline   Reply With Quote
Old 01-05-2009, 12:28 AM   #8 (permalink)
New Member
 
Join Date: Jul 2008
Posts: 31
pendraggon87 is an unknown quantity at this point
Default

[rates count] wouldnt work, since that is being called in the view controller, not the app delegate. Here are two methods I have: the first method will automatically download the information and write everything into the preferences every time. This way works. The second method checks the updated time etc. and then downlods as needed - this is where i have problems.

Method 1:
Code:
-(void)loadPreferences {
	NSUserDefaults *defaults = [[NSUserDefaults standardUserDefaults] retain];
	//For testing, download anew every time.
	[defaults setObject:@"EUR" forKey:@"ExchangeBaseCurrCode"];
	[rootViewController.mainViewController setActivityAnimation:AIStart];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSError *parseError = nil;
	XMLParser *parser = [[XMLParser alloc] init];
	[parser parseXMLFileArURL:[NSURL URLWithString:EURO_RATE_XML_URL] parseError:&parseError del:self];
	[parser release];
	[pool release];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	[rootViewController.mainViewController setActivityAnimation:AIStop];
}
Method 2:
Code:
-(void)loadPreferences {
	NSUserDefaults *defaults = [[NSUserDefaults standardUserDefaults] retain];
	if([defaults objectForKey:@"ExchangeRatesLastUpdated"]==nil){
		//Running for the first time.
	}
	else {
		NSDate *today = [NSDate dateWithNaturalLanguageString:@"today at 00:00 +0000"];
		NSDate *updated = (NSDate *)[defaults objectForKey:@"ExchangeRatesLastUpdated"];
		if([updated earlierDate:today]&&[updated isEqualToDate:today]==NO){
			//Need to update
			self.rates = [[defaults objectForKey:@"ExchangeRateDict"] retain];
			[self updateRates];
		}
		else {
			//Up to date
			self.rates = [defaults objectForKey:@"ExchangeRateDict"];
		}
	}
}
-(void)updateRates{
	[rootViewController.mainViewController setActivityAnimation:AIStart];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSError *parseError = nil;
	XMLParser *parser = [[XMLParser alloc] init];
	[parser parseXMLFileArURL:[NSURL URLWithString:EURO_RATE_XML_URL] parseError:&parseError del:self];
	[parser release];
	[pool release];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	[rootViewController.mainViewController setActivityAnimation:AIStop];
}
pendraggon87 is offline   Reply With Quote
Old 01-05-2009, 01:26 AM   #9 (permalink)
Registered Member
 
Join Date: Dec 2008
Posts: 77
aceallways is on a distinguished road
Default

Probably not it but this once happened to me and the problem was not w/ my code.

Recreating the project and copying in all the code made it work.

It happens if you open 2 projects at once in xcode and then try to build, the building project becomes screwed for good.
aceallways is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 400
16 members and 384 guests
7twenty7, blasterbr, buggen, chiataytuday, Clouds, dre, fiftysixty, HemiMG, jimmyon122, jonathandeknudt, LEARN2MAKE, n00b, nyoe, pungs, tymex, UMAD
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,668
Threads: 94,121
Posts: 402,902
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jonathandeknudt
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 03:59 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0