Instance variables lose value after initWithNib and before IBAction in NSViewController

混江龙づ霸主 提交于 2019-12-12 13:35:24

问题


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


回答1:


You should declare the property as (copy) instead of (assign)




回答2:


Have you tried declaring them as (nonatomic, retain)?




回答3:


Allow me to answer this since the correct answer is buried in the comments in my question.

I figured out what I was doing wrong. I was adding a view controller to each of my nibs that represented the controller for the view. Then I was attaching the button clicks to that separate view controller object. @Francis-McGrew attached a project that showed me that I should be attaching the button clicks to the File Owner, then setting the file owner to be the view controller. There is basically no need to import a second view controller into the nib when you can just use file owner as a placeholder instead.



来源:https://stackoverflow.com/questions/8590853/instance-variables-lose-value-after-initwithnib-and-before-ibaction-in-nsviewcon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!