PDA

View Full Version : app crashes! need help with cocoa app (files attached)




Darkroom
Mar 7, 2008, 03:54 PM
i'm having a major problem with the app that i'm building. i'm quite new to cocoa so a lot of the code is snipped and tailored to (attempt to) make it work...

the app is finished essentially, and all there is remaining that i'd like to do is have the app save the size/position of the window (which is done), but also make the main window's color be saved from the last launch. unfortunately, the window color starts on black (i want it to default on white) and when the app's window size/position or color is changed and then the app is closed and relaunched, it crashes...

if someone could please please please download my files here (http://www.imagectrl.com/Light2TestCode.zip), have a look at them, and tell me what is wrong i would very very very much appreciate it. again, i wouldn't so much as call myself a coder, and i'm not the fastest learner in the world, so if you give me some advice in this thread, please make sure you pretend your talking to a 5 year old ;).

thanks so much in advance.



kainjow
Mar 7, 2008, 04:05 PM
In windowColor, you need to use proper memory management. fillColor should be retained when you assign it. If you had GC enabled you wouldn't need to do this but it looks like you're targeting 10.4.

So when you do this:

fillColor = [NSColor whiteColor];

Do this instead:

[fillColor release];
fillColor = [[NSColor whiteColor] retain];

And the same for the other places.

I couldn't get it to crash except one time.


As for saving colors, check out Storing NSColor in User Defaults (http://developer.apple.com/documentation/Cocoa/Conceptual/DrawColor/Tasks/StoringNSColorInDefaults.html).

Darkroom
Mar 7, 2008, 04:12 PM
ok... so i added the retain code to my files, and it seems to have worked... thank you very much... my color and window position user defaults seem fine...

the only problem i'm having now is on first launch, the NS User Default windowColor is turning up black, instead of blue as my code states. i'm assuming this black is just a non-color, like the code isn't seeing any set user default for the window color.

finally, as i mentioned in a private message, my NSColorPanel has a hud style attached to it, it's a style hack that someone told me about a while ago (i think it was you actually?). when i switch my app to the 10.5 SDK this style hack causes problems, so it's why i left everything to be compiled with the 10.4 Universal SDK... however, you mentioned that the hud window isn't even compatible with 10.4? i know native hud windows with interface builder don't work in 10.4, but am i wrong in assuming that this style hack will still show up in 10.4 - it being a hack and the fact that the NSColorPanel can't be a hud window natively, and it allows me to compile without any problems... i mean, do you think the NSColorPanel will look like a normal NSColor Panel in 10.4?

Darkroom
Mar 7, 2008, 08:53 PM
here's my code for my user defaults for the colorWindow:

in my colorController.m file, i have this:


+ (void)initialize {
[[HUDColorPanel class] poseAsClass:[NSColorPanel class]];
NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[NSColor blueColor]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *myDefaults = [NSDictionary dictionaryWithObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
[defaults registerDefaults:myDefaults];
}

// etc.


and in my colorWindow.m file i have this:


- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSData *defaultViewColorData = [[NSUserDefaults standardUserDefaults] dataForKey:DEFAULTS_VIEW_COLOR_KEY];
if (defaultViewColorData != nil) {
[fillColor release];
fillColor = [[NSUnarchiver unarchiveObjectWithData:defaultViewColorData] retain];}
}
return self;
}

//etc.


as far as i can tell, everything is in place correctly... when i trash my prefs file and relaunch the app, it still defaults at a black color instead of a blue color... any thoughts?

Darkroom
Mar 7, 2008, 09:08 PM
ok... so for some magical reason it now works... i don't think i did anything to the code though... could this be a bug?

Darkroom
Mar 7, 2008, 09:14 PM
woops! spoke too soon... now it doesn't work again... ??? colorWindow still defaults on black color instead of blue color... this is so crazy...:rolleyes:

Eraserhead
Mar 8, 2008, 03:37 AM
Sounds like it could be a bug in the API...

Darkroom
Mar 8, 2008, 08:44 AM
it's very strange. sometimes it works, and sometimes it doesn't... i guess it's not that big of a deal... it's just that since i'm a novice it's next to impossible to know weather something is a bug, as 99.9% of the time it's gonna be my fault.

kainjow
Mar 8, 2008, 11:41 AM
It's probably a memory issue. Post the code where you're saving the color value to user defaults.

Darkroom
Mar 8, 2008, 11:48 AM
It's probably a memory issue. Post the code where you're saving the color value to user defaults.

here's the code: (i've changed my default windowColor to be white, not blue)

ColorController.h

#import <Cocoa/Cocoa.h>
#import "windowColor.h"

@interface ColorController : NSObject {
IBOutlet windowColor *myColorSelection;
IBOutlet windowColor *myWhiteSelection;
NSTimer *timer;
}

- (IBAction)selectColor:(id)sender;
- (IBAction)selectWhite:(id)sender;


@end


ColorController.m

#import "ColorController.h"
#import "windowColor.h"
#import "HUDColorPanel.h"

@implementation ColorController

+ (void)initialize {
[[HUDColorPanel class] poseAsClass:[NSColorPanel class]];
NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[NSColor whiteColor]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *myDefaults = [NSDictionary dictionaryWithObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
[defaults registerDefaults:myDefaults];
}

- (id)init {
if (self = [super init]) {
[[NSColorPanel sharedColorPanel] setDelegate:self];
}
return self;
}

- (IBAction)selectColor:(id)sender {
if ([[NSColorPanel sharedColorPanel] isVisible]) {
[[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil];}
else {
[[NSColorPanel sharedColorPanel] makeKeyAndOrderFront:nil];
[[NSColorPanel sharedColorPanel] setAlphaValue:0.0];
timer = [[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(colorPanelFadeIN:) userInfo:nil repeats:YES] retain];
}
}

- (void)colorPanelFadeIN:(NSTimer *)theTimer
{
if ([[NSColorPanel sharedColorPanel] alphaValue] < 1.0) {
[[NSColorPanel sharedColorPanel] setAlphaValue:[[NSColorPanel sharedColorPanel] alphaValue] + 0.1];
}
else
{
[timer invalidate];
[timer release];
timer = nil;
}
[[NSColorPanel sharedColorPanel] setTarget:myColorSelection];
[[NSColorPanel sharedColorPanel] setAction:@selector(changeColor:)];
}

- (BOOL)windowShouldClose:(id)window
{
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(colorPanelFadeOUT:) userInfo:window repeats:YES];
return NO;
}

- (void)colorPanelFadeOUT:(NSTimer *)theTimer
{
NSWindow* window = [timer userInfo];
[window setAlphaValue:[window alphaValue] -0.1];
if([window alphaValue] <= 0.0)
{
[timer invalidate];
[window close];
}
}

- (IBAction)selectWhite:(id)sender
{
setTarget:myWhiteSelection;
[myWhiteSelection changeWhite:nil];
}


@end


windowColor.h


#import <Cocoa/Cocoa.h>

@interface windowColor : NSView {
NSColor *fillColor;
}

- (IBAction)changeColor:(id)sender;
- (IBAction)changeWhite:(id)sender;


@end


windowColor.m

#import "windowColor.h"

@implementation windowColor

- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSData *defaultViewColorData = [[NSUserDefaults standardUserDefaults] dataForKey:DEFAULTS_VIEW_COLOR_KEY];
if (defaultViewColorData != nil) {
[fillColor release];
fillColor = [[NSUnarchiver unarchiveObjectWithData:defaultViewColorData] retain];}
}
return self;
}

- (void)dealloc {
[super dealloc];
[fillColor release];
}

- (IBAction)changeColor:(id)sender {
NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[sender color]];
[[NSUserDefaults standardUserDefaults] setObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
[fillColor release];
fillColor = [[sender color] retain];
[self setNeedsDisplay:YES];
}

- (IBAction)changeWhite:(id)sender {
NSData *defaultViewColorData = [NSArchiver archivedDataWithRootObject:[NSColor whiteColor]];
[[NSUserDefaults standardUserDefaults] setObject:defaultViewColorData forKey:DEFAULTS_VIEW_COLOR_KEY];
[fillColor release];
fillColor = [[NSColor whiteColor] retain];
[self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)rect {
[fillColor set];
NSRectFill(rect);
}


@end