【发布时间】:2011-12-21 13:51:18
【问题描述】:
我正在编写的 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 中初始化实例变量,只初始化一次,并让它们在控制器的生命周期内保持它们的值?
谢谢
凯夫
【问题讨论】:
-
我已将您的代码复制到一个测试项目中,它工作正常。您的设置有误,可能是在 NIB 中。尝试创建一个新项目并使用 Xcode 自动生成的现有 MainView.xib。
-
有什么方法可以将您的测试项目的 zip 文件发送给我,以便我比较两者吗?谢谢。
-
谢谢!谢谢!谢谢!我弄清楚我做错了什么。我正在向代表视图控制器的每个笔尖添加一个视图控制器。然后我将按钮点击附加到那个单独的视图控制器对象。您的项目向我展示了我应该将按钮单击附加到文件所有者,然后将文件所有者设置为视图控制器。当您可以只使用文件所有者作为占位符时,基本上不需要将第二个视图控制器导入笔尖。再次感谢!
标签: objective-c xcode macos cocoa nsviewcontroller