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

Mockup & CodeGen, iPhone & iPad
($9.99)

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

Manu
($0.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 04-18-2009, 01:29 PM   #1 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default drawRect = EXC_BAD_ACCESS (crash problem)

When I try to start my drawRect using an image found from a NSUserDefaults default, it crashes the app with a 'EXC_BAD_ACCESS' error. Once I remove the code to a static image value for imagePathB, the code runs with no errors.

Anyone know why my loading the NSUserDefaults would result in this error?

Code:
- (void)drawRect:(CGRect)rect {

	NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
	imagePathB = [prefs stringForKey:@"Image"];
	myUIImage = [UIImage imageNamed:[prefs stringForKey:@"Image"]];
DGYWFT is offline   Reply With Quote
Old 04-19-2009, 02:15 AM   #2 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

Anyone?
DGYWFT is offline   Reply With Quote
Old 04-19-2009, 02:51 AM   #3 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

It's hard to see what's wrong from just those 3 lines. Those seem fine, except for the fact that imagePathB is not used.

As a general design point, though, it seems like you're doing more in your drawRect than you should be doing. It seems like you want to decide on an image and load it at some other time than when the system is trying to draw your view.
eddietr is offline   Reply With Quote
Old 04-19-2009, 06:13 AM   #4 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

In the correct version of the code the imagePathB is used, I pasted a code I was still tweaking with. Yeah, in my drawRect I draw my image, place it into a layer, then draw another image and place it into a layer, done. The user may change the image they want at different times, thus having to call drawrect again view setneedsdisplay to redraw the view. I am using this method becuase I need some custom drawing involving multiply modes with colors over images, and this seems the only method of achieving that, since layer effects are not on the iphone, from what the documentation says.

Is there really a sort of limit on how much you should be doing in the draw rect? Should I be sending code to the drawrect instead of the code inside it?
DGYWFT is offline   Reply With Quote
Old 04-19-2009, 12:56 PM   #5 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by DGYWFT View Post
In the correct version of the code the imagePathB is used, I pasted a code I was still tweaking with.
Well, if you need help debugging something, then you need to post the current and correct version of the code. Otherwise how can anyone help you find the bug that is causing the crash?

Quote:
Is there really a sort of limit on how much you should be doing in the draw rect? Should I be sending code to the drawrect instead of the code inside it?
You just want to minimize what you do there. So it seems like you're looking for an loading an image in there. Why not have that preloaded in RAM, for example?
eddietr is offline   Reply With Quote
Old 04-19-2009, 01:09 PM   #6 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

Right, just pointing to the issue the nuserdefaults was killing the app. Anyways, updated the code, and might have found the issue. I was running almost the same code on the init of the viewcontroller, which might have been trying to open and save the value at the same time as drawrect, causing the error. So now its only called in drawrect:


Code:
- (void)drawRect:(CGRect)rect {

	NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
	imagePathB = [prefs stringForKey:@"Image"];
	
	if (imagePathB == nil) {
		NSLog(@"Loaded no Value!");
		[prefs setObject:@"test.png" forKey:@"Image"];
		[prefs synchronize];
		imagePathB = [prefs stringForKey:@"Image"];
		NSLog(@"Drawrect with imagePath = %@", imagePathB);
	}
	
	imagePathB = [prefs stringForKey:@"Image"];
	myUIImage = [UIImage imageNamed:imagePathB];
As far as grabbing the image from ram, not sure how to do that. My users will be choosing the image from a tableview, them coming back to this view to see the image they have. But that image also has custom drawing on it, thus why I am calling this drawrect with new image values from time to time.

The app now runs on the device without an issues like before, but I still have to do more testing and turn the animation back onto the CALayer to see if it kills it. Well see...
DGYWFT is offline   Reply With Quote
Old 04-19-2009, 01:22 PM   #7 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Well, my point is that checking to see if a key exists in the prefs, and then writing a default value of that key if needed, etc, are things that you don't want to do inside drawRect. All that logic can be done when the view is loaded (or when the user selects something from the tableview).

That really should all be taken care of and an UIImage loaded from flash (like your last line you posted) *before* this point.

Then go about your custom drawing (and nothing else) in drawRect.
eddietr is offline   Reply With Quote
Old 04-20-2009, 12:15 AM   #8 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

Eddie,
I think that all sounds great in theory and the right way, but everytime I try that, its back to the error. For example I define it in the viewcontroller, and then try this instead:

Header :

Code:
#import <UIKit/UIKit.h>
@class MainViewController; 

@interface MainView : UIView {
	UIImage			*myUIImage;
	MainViewController *mvc;
}

@property (nonatomic, retain) UIImage	*myUIImage;
@property (nonatomic, retain) MainViewController *mvc;
@end

Methods:
Code:
#import "MainView.h"
#import "MainViewController.h"
#import <QuartzCore/QuartzCore.h>

@implementation MainView
@synthesize myUIImage, mvc;

- (void)drawRect:(CGRect)rect {
	
	NSLog(@"drawRect go");
	myUIImage = [UIImage imageNamed:mvc.imagePath]; // Code breaks here
	NSLog(@"drawRect go again"); // This never runs
DGYWFT is offline   Reply With Quote
Old 04-20-2009, 12:46 AM   #9 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

When you say "code breaks" what exactly is happening?

And, actually, [UIImage imagedNamed:] is going to load that image from the bundle into RAM. I still wouldn't do that within drawRect.

But in any case, let's fix the problem first I guess. Are you sure mvc.imagePath gives you the correct path?
eddietr is offline   Reply With Quote
Old 04-20-2009, 12:51 AM   #10 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

I get the EXC_BAD_ACCESS error. The path is right and it loads the image from userdefaults on load. But right away the app craps out. So, if you cannot run any variables in the drawrect, like a value for the image path, then how do you get an image into drawrect when you want to change?
DGYWFT is offline   Reply With Quote
Old 04-20-2009, 12:55 AM   #11 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by DGYWFT View Post
I get the EXC_BAD_ACCESS error.
So what does the stack trace looks like?

Quote:
So, if you cannot run any variables in the drawrect, like a value for the image path, then how do you get an image into drawrect when you want to change?
Just load the UIImage before the drawRect and store it as an instance variable.
eddietr is offline   Reply With Quote
Old 04-20-2009, 04:39 AM   #12 (permalink)
New Member
 
Join Date: Feb 2009
Location: Bangkok
Posts: 145
Default

Thats what I was saying, is if I load it somewhere else, that just results in a crash because it seems they are both trying to work on that process. But after monitoring and cleaning memory leaks, tweaking code elft and right, I got the ram and leaks all polished and nice now.

So this code works with no problems (for now) at the start of drawRect:


Code:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
	imagePathB = [prefs stringForKey:@"Image"];
	
	if (imagePathB == nil) {
		NSLog(@"Loaded no Value!");
		[prefs setObject:@"test.png" forKey:@"Image"];
		[prefs synchronize];
		imagePathB = [prefs stringForKey:@"Image"];
		NSLog(@"Drawrect with imagePath = %@", imagePathB);
	}
	
	imagePathB = [prefs stringForKey:@"Image"];
	myUIImage = [UIImage imageNamed:imagePathB];
DGYWFT is offline   Reply With Quote
Reply

Bookmarks

Tags
drawrect, nsuserdefaults

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: 230
16 members and 214 guests
ADY, Alsahir, cacao, dacapo, Dani77, Desert Diva, djohnson, F_Bryant, HemiMG, jansan, M@realobjects, MarkC, prchn4christ, smethorst, spiderguy84
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,882
Threads: 89,228
Posts: 380,762
Top Poster: BrianSlick (7,129)
Welcome to our newest member, jansan
Powered by vBadvanced CMPS v3.1.0

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