Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
I'm trying to get a savePanel working, just.. because. So, I'm using NSSavePanel. I have a simple application, all it has is a so far useless textfield, and a save button. I have outlets that are definitely going to the window (in case I decide to do a sheet) and to the textfield. (for when this is "done") I also have an action coming from the save button. I KNOW my connections are good. Here's my class files:

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject {
NSSavePanel *savePanel;
IBOutlet id savingPanel;
IBOutlet id text;
IBOutlet id myWindow;
}
- (IBAction)savePressed:(id)sender;
@end


#import "AppController.h"

@implementation AppController
- (IBAction)savePressed:(id)sender {
[savePanel runModalForDirectory:mad:"" file:mad:""];
}

- (void)awakeFromNib {
[savePanel setTitle:mad:"Save game"];
[savePanel setPrompt:mad:"Save"];
[savePanel setCanCreateDirectories:1];
}
@end



I don't get any errors, it runs. But pressing save does NOTHING. Nothing changes. What's wrong?
 

MrFusion

macrumors 6502a
Jun 8, 2005
613
0
West-Europe
I'm trying to get a savePanel working, just.. because. So, I'm using NSSavePanel. I have a simple application, all it has is a so far useless textfield, and a save button. I have outlets that are definitely going to the window (in case I decide to do a sheet) and to the textfield. (for when this is "done") I also have an action coming from the save button. I KNOW my connections are good. Here's my class files:

@end



I don't get any errors, it runs. But pressing save does NOTHING. Nothing changes. What's wrong?

It seems to me that you are not initializing an NSSavePanel.
Use
Code:
+ (NSSavePanel *)savePanel;
There is also only one shared panel, if I am not mistaken.
Your savePanel is not pointing to any object.
 

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
I thought I was initializing it by declaring it...
NSSavePanel *savePanel;
This should both init it and point to the one I just created.
 

Cromulent

macrumors 604
Oct 2, 2006
6,816
1,101
The Land of Hope and Glory
I thought I was initializing it by declaring it...
NSSavePanel *savePanel;
This should both init it and point to the one I just created.

Nope. That is not how pointers work. All you have done is said savePanel points to a location in memory that contains an NSSavePanel. But you haven't actually got an NSSavePanel for it to point too nor have you actually told it where in memory it is pointing. Basically it is just a junk memory reference that could contain anything.

Consider this:

If you have a pointer to char (char *someVar) and you write to it, where does what you have written go if you have not initialised the pointer?
 

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
ok, looking back at my hillegas book I remember init stuff now. Where do I do initializing though? Does it need its own special method, or can I do it in the header?
 

MrFusion

macrumors 6502a
Jun 8, 2005
613
0
West-Europe
ok, looking back at my hillegas book I remember init stuff now. Where do I do initializing though? Does it need its own special method, or can I do it in the header?

Not in the header, for certain.
Where you do it, is up to you.
Variables declared in the header are accessible everywhere in your class. These are usually initialized in an init method. Variables local to your method are allocated and initialized in the method you need them.

Don't forget to release these when you are done with them!

header:
Code:
NSString *stringOne;
NSString *stringTwo;

Implementation:

Code:
- (id) init {
	self = [super init];
	if (self != nil) {	
          stringOne = [[NSString alloc] initWithString:@"one"]; //don't forget to release
          stringTwo = [NSString stringWithString:@"two"]; // you did not initialized this one. has been done for you
        }
 return self;
}

-(void) printAll {
 NSString *stringThree = [[NSString alloc] initWithString:@"3"]; //don't forget to release
 NSString *stringFour = [NSString stringWithString:@"4"]; // you did not initialized this one. has been done for you
       
 NSLog(@"%@ %@ %@",stringOne,stringTwo,stringThree,stringFour);
 [stringThree release];

 [stringOne release]; // global variable is released, and replaced in the next line
 stringOne = [[NSString alloc] initWithString:@"new"]; //don't forget to release, if you comment this line out, your program should crash
 NSLog(@"%@ %@",stringOne,stringTwo,stringFour);
}
-(void) dealloc {
  [stringOne release];
 [super dealloc];
}
 

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
ok I have an - (id) init {} method, and I put:
[savePanel init];
savePanel=[NSSavePanel savePanel];
return self;

This does not give any errors, but when I run the program and click save it freezes. More accurately in xcode it says loading gdb debugger when I click save. And the savepanel never comes up.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
ok I have an - (id) init {} method, and I put:
[savePanel init];
savePanel=[NSSavePanel savePanel];
return self;

This does not give any errors, but when I run the program and click save it freezes. More accurately in xcode it says loading gdb debugger when I click save. And the savepanel never comes up.

Don't do this. For the majority of the time, save/open panels really only need to be created when you're going to use them. For example:

Code:
- (IBAction)saveFile:(id)sender {
    NSSavePanel *savePanel = [NSSavePanel savePanel];
    // customize savePanel here...
    if ([savePanel runModal] == NSOKButton)
        // user chose a file accessible via [savePanel filename]
}
 

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
ok thanks :) but will that fix my problem of it not running?

Also, some init questions if you don't mind.

Does [super init]; cover all initializing that's needed for every object?

Do I need [outlet init]; ?
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
ok thanks :) but will that fix my problem of it not running?

Most likely, unless you're not showing us all of your code :)

Does [super init]; cover all initializing that's needed for every object?

Whatever initXXX method you're overriding in your subclass, always call [super initXXX]. Although with NSObject this isn't really necessary, but it's a good habit to get into.

Do I need [outlet init]; ?

No. any IButlet connected in Interface Builder gets initialized automagically by the nib-loading process. If you need to do any further customization of nib objects, do it in awakeFromNib.
 

liptonlover

macrumors 6502a
Original poster
Mar 13, 2008
989
0
Sorry for double post but I made the corrections, so I'd like to share the working product in case anyone else needs help with it

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject {
//don't create a pointer to the savepanel here.
IBOutlet id savingPanel;
IBOutlet id text;
IBOutlet id myWindow;
}
- (IBAction)savePressed:(id)sender;
@end



#import "AppController.h"

@implementation AppController
- (IBAction)savePressed:(id)sender {
//create the pointer and create the object it points to.
NSSavePanel *savePanel=[NSSavePanel savePanel];
//the most basic easiest method to open an NSSavePanel. Check out the class file to see the additional options.
[savePanel runModal];
}

- (void)awakeFromNib {
}

- (id)init {//init file.
[super init];
return self;
}
@end


Thanks for your help guys!
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
sorry I meant pointer. Like [savePanel(my pointer) init];

Each class is different. You need to read the docs. In this instance with NSSavePanel, you only call the savePanel method, not alloc/init. Other objects you will have to call alloc/init. It depends on what the designated initializer is for each class.

Don't call init by itself. You use alloc/init together. alloc creates the object in memory, and init initializes it.

I would suggest reading Introduction to Memory Management Programming Guide for Cocoa
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.