3

我正在编写的 OS X 应用程序有一个非常基本的初始化问题。我在我的 NSViewController 的 initWithNibName 中初始化实例变量。但是,当我在 IBAction 方法中访问它们时,这些变量失去了它们的值并最终等于 nil。

这是我的代码。我有一个具有 1 个主窗口和 1 个 NSViewController 的应用程序。应用程序委托在 applicationDidFinishLoading 中以编程方式调用 initWithNibName。出现视图,视图中的按钮成功调用onButtonClick。但是,在该方法中,myString 的值为 null。日志清楚地显示它在 initWithNibName 方法期间成功初始化。所以它在 initWithNibName 和按钮点击之间失去了它的价值。

//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)

如何让 myString 保留其价值?

我已经尝试了我能想到的所有类型的属性声明。我还尝试了各种赋值方法([self setMyString]、self.myString = @"blah"、myString = [NSString stringWithFormat:@"blah"] 等)。

我已经读过我应该在 awakeFromNib() 中进行初始化。这确实有效。但是,我最终的初始化代码将包括一系列 [[MyObj alloc] init] 调用,当它们被多次调用时,会产生多个指针,这很疯狂。我的最终目标是拥有一个指向对象的指针,控制器可以始终引用并始终获取相同的数据。对象由控制器初始化,控制器保存引用并在用户与控制器交互时根据需要更新它。

那么有没有办法在 NSViewControllers 中初始化实例变量一次,并让它们在控制器的生命周期内保持它们的值?

谢谢

凯夫

4

3 回答 3

1

您应该将属性声明为 (copy) 而不是 (assign)

于 2011-12-21T13:53:19.407 回答
0

您是否尝试将它们声明为(非原子,保留)?

于 2011-12-21T13:59:10.153 回答
0

请允许我回答这个问题,因为正确答案隐藏在我问题的评论中。

我弄清楚我做错了什么。我正在向代表视图控制器的每个笔尖添加一个视图控制器。然后我将按钮点击附加到那个单独的视图控制器对象。@Francis-McGrew 附加了一个项目,显示我应该将按钮单击附加到文件所有者,然后将文件所有者设置为视图控制器。当您可以只使用文件所有者作为占位符时,基本上不需要将第二个视图控制器导入到 nib 中。

于 2011-12-22T00:38:02.030 回答