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 07-06-2010, 05:55 AM   #1 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 3
Lukonian is on a distinguished road
Default UINavigationController navigation & “EXC_BAD_ACCESS”

Hey all,

I'm quite new to iPhone dev so I am hoping this might be resolved quite easily.

I have created a navigation based project in Xcode. The default view controller ( as setup by the navigation application template ) is a table view. I have created two sub view controllers, SubViewOneController and SubViewTwoController. The order of navigation is...

defaultViewController --> subViewOneController ---> subViewTwoController

So from the default view you click on the table cell which pushes subViewOneController to the navigation controller...

[[self navigationController] pushViewController:subViewOneController animated:YES];

Then, there is a button in subViewOne which creates and pushes subViewTwoController to the navigations controller's stack, so inside subViewOneController's implementation I have...

SubViewTwoController *subViewTwo = [[SubViewTwoController alloc] initWithNibName:@"SubViewTwoController" bundle:nil];
NSString *subViewString = [NSString stringWithFormat:@"Sub view 2"];

[[appDelegate navigationController] pushViewController:subViewTwo animated:YES];
[[subViewTwo label] setText:subViewString];

This all works until I track back through the navigation for the 2nd time. I.E.

defaultViewController --> subViewOneController ( OK ) ---> subViewTwoController ( OK )( click back button ) ---> subViewOneController ( OK ) ---> subViewTwoController ( OK )( click back button ) ---> "EXC_BAD_ACCESS”

I am not sure why this is happening. As far as I know “EXC_BAD_ACCESS” is normally caused by memory problems but UINavigationController is meant to handle that for you.

I need help to debug this; what method does the back button call? I've counted the number of controllers in navigationController.viewControllers and that has been correct. So why when I click sub view two's back button the second time do I get this error?

Thanks in anticipation
Lukonian
Lukonian is offline   Reply With Quote
Old 07-06-2010, 07:28 AM   #2 (permalink)
el guaje
 
kevinyide's Avatar
 
Join Date: Jun 2010
Posts: 243
kevinyide is on a distinguished road
Send a message via Yahoo to kevinyide
Default

i had a similar problem which seem to get fixed once i released my viewController once i was done using it.
[SubViewTwo release];

Not sure though if its the same case with you.
Does the same problem happen when you navigate to your root view & then push your View One?

Code:
[[self navigationController] pushViewController:subViewOneController animated:YES];

[[appDelegate navigationController] pushViewController:subViewTwo animated:YES];
i think [self navigationController] should suffice instead of using appDelegate.

Last edited by kevinyide; 07-06-2010 at 07:31 AM.
kevinyide is offline   Reply With Quote
Old 07-06-2010, 07:39 AM   #3 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

There is nothing magical about navigation controllers when it comes to memory management. If you push a view controller, it will be retained, if you pop one, it will be released.

The symptoms you describe point to something being over-released, probably in the subViewTwoController.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 07-06-2010, 11:05 AM   #4 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 3
Lukonian is on a distinguished road
Default

Resolved...

It was down to a couple of lines of code...

NSString *displayString = [NSString stringWithFormat:@"Set by %@", [self title]];
[appDelegate setModelData:displayString];

I've come from an ActionScript background and to me, referencing displayString would prevent it from being trashed. However, in objective-c this is not the case and NSString stringWithFormat is an autorelease method so when subViewOne was trying to get the string, [appDelegate getModelData] was pointing to invalid data because garbage collection had cleared the object created with NSString stringWithFormat.

I hope you are following this.

The resolution was to change NSString stringWithFormat to this...

NSString *displayString = [[NSString alloc] initWithFormat:@"Set by %@", [self title]];
[appDelegate setModelData:displayString];

and clear any existing pointers in the setModelData method...

-(void) setModelData : (NSString *) newData {
if (modelData != nil)
{
[modelData release];
}
modelData = newData;
}


I suspect there will be more memory management lessons coming my way
Lukonian is offline   Reply With Quote
Old 07-06-2010, 11:12 AM   #5 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Code:
NSString *displayString = [[NSString alloc] initWithFormat:@"Set by %@", [self title]];
[appDelegate setModelData:displayString];
You are now leaking displayString.

Code:
-(void) setModelData : (NSString *) newData {
	if (modelData != nil)
	{
		[modelData release];
	}
	modelData = newData;
}
If modelData is a property, then just use the standard setter you get with synthesizing that property. If it isn't a property, it should be.

As is, you have a couple of issues here.

For one, just because modelData is not nil, does NOT inherently mean it should be released.

A good example of why not is your last line, where you simply do straight assignment, without a retain or copy.

You might get away with it once, but it should crash the second time around.

Edit: also, there is no garbage collection currently on the iPhone. The object you had previously was autoreleased, which is not the same as garbage collection.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 07-07-2010, 11:24 AM   #6 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 3
Lukonian is on a distinguished road
Default

Are you sure [modelData release] doesn't release displayString?
Lukonian is offline   Reply With Quote
Old 07-07-2010, 11:37 AM   #7 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Not on the first pass. And if you send in an autoreleased object, you're dead.

This is a fundamentally flawed setter you have here. For all of the good it is doing, you might as well rewrite it like this:

Code:
-(void) setModelData : (NSString *) newData
{
	[modelData release];

	modelData = newData;
}
Since sending a message to nil doesn't do anything, there is no real reason for your test. So what you have here is a method that does nothing but release old data whenever something is passed in. But you don't retain the new data. Which means next time around, when the new data is now the old data, it will be released, even though you don't want to.

Just use the standard setter until 1) you understand memory management, and/or 2) you have a need for custom behavior. Even if you are fully accounting for the bad behavior here elsewhere in code - which you obviously are not, hence your crashing - you are totally defeating the purpose of having a good setter in the first place.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick 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: 330
8 members and 322 guests
anothermine, Chickenrig, firecall, givensur, iNet, michaelhansen, PixelInteractive, stanny
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,657
Threads: 94,118
Posts: 402,892
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jenniead38
Powered by vBadvanced CMPS v3.1.0

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