I have a very basic initialization problem with an OS X app I am writing. I am initializing instance variables in initWithNibName in my NSViewController. However, these variables lose their value and end up being equal to nil by the time I access them in my IBAction methods.
Here is my code. I have an application that has 1 main window, and 1 NSViewController. The app delegate is programatically calling initWithNibName in applicationDidFinishLoading. The view appears, and the button in the view successfully calls onButtonClick. However, in that method, the value of myString is null. The logs clearly show that it was successfully initialized during the initWithNibName method. So it lost its value between initWithNibName and the button click.
//MyAppDelegate.m
@implementation MyAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
MainView* mainViewController = [[MainView alloc] initWithNibName:@"MainView" bundle:[NSBundle mainBundle]];
[mainViewController loadView];
NSView *controllerView = [mainViewController view];
[window setContentView:controllerView];
}
@end
//MainView.h
@interface MainView : NSViewController {
NSButton *myButton;
NSString* myString;
}
@property (assign) IBOutlet NSButton *myButton;
@property (assign) NSString* myString;
- (IBAction)onMyButtonClick:(id)sender;
@end
//MainView.m
@implementation MainView
@synthesize myButton;
@synthesize myString;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
NSLog(@"initWithNibName");
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code here.
NSLog(@"Initializing...");
[self setMyString:@"try to set the variable"];
NSLog(@"String is %@", myString);
}
return self;
}
- (void)awakeFromNib {
NSLog(@"awakeFromNib");
//[self setMyString:@"init in here works, but is called too many times"];
}
- (IBAction)onMyButtonClick:(id)sender{
NSLog(@"Button clicked");
NSLog(@"%@", myString); //Always nil when initialized in initWithNibName()!!
}
@end
//Logs
initWithNibName
Initializing...
String is try to set the variable
awakeFromNib
awakeFromNib
Button clicked
(null)
How can I get myString to retain its value?
I have tried every type of property declaration I can think of. I have also tried various methods of assignment ([self setMyString], self.myString = @"blah", myString = [NSString stringWithFormat:@"blah"], etc).
I have read that I should do my initialization in awakeFromNib(). This actually does work. However, my eventual initialization code will include a series of [[MyObj alloc] init] calls, and when they get called multiple times, multiple pointers result and it's madness from there. My end goal is to have one pointer to an object, which the controller can always refer to and always get the same data. The object gets initialized by the controller, which holds the reference and updates it as needed as the user interacts with the controller.
So is there any way to initialize instance variables in NSViewControllers, only once, and have them retain their value for the life of the controller?
Thanks
Kev