我是Cocoa/Obj-C编程新手。
我有相当简单的应用程序(目标平台Mac OSX 10.5和10.6),我的背景是C/C++系统编程。
我有一个主窗口,其中包含一些文本字段,按钮,属性等。我设置了出口和操作(希望正确)。在另一个 NIB 中声明的其他窗口在单击其中一个按钮时加载:
- (IBAction) openSettings: (id) sender
{
ConfigurationWindowController * wc=[[ConfigurationWindowController alloc] initWithWindowNibName:@"Configuration"];
[wc showWindow:self];
}
正在加载并显示新窗口。
我需要做以下事情:1) 将一些字符串参数传递给第二个("子")窗口2) 当第二个窗口关闭时,将此参数接收回主窗口。
我不确定在可可中做到这一点的正确方法是什么。
@sergio :非常感谢您的回复!在我的"子"窗口中,我在打开子窗口之前存储指向主窗口的指针,我传递了一些参数:
ConfigurationWindowController * wc=[[ConfigurationWindowController alloc] initWithWindowNibName:@"Configuration"];
mConfigWindow = wc;
[mConfigWindow setValuesToURL:@"some string here" storageParam:@"another string" callerWindowPtr:self];
[wc showWindow:self];
此方法已成功调用 我看到存储在"子"窗口类实例属性中的值。但是当我尝试将此值分配给 setValuesToURL 方法中的文本文件时,GUI 元素仍然为空,我尝试在 awakeFromNib 方法中分配存储的字符串,但这里这些属性为 null! .self 指针的值也不同 - 这意味着创建的对象 initWithWindowNibName 和带有 GUI 的实际窗口是不同的。显然,当我尝试传回值时,存储的指向"主"窗口的指针也是空的。我怀疑问题出在 NIB 设置 - 对我来说真的很困惑。 我怀疑是对代码/NIB关系的常见误解,我尝试了不同的东西,但仍然无法使其正常工作。任何指导都将非常有用。
-(void) setValuesToURL:(NSString*)strServiceURL storageParam:(NSString*) strStorageURL callerWindowPtr:(AppletAppDelegate *)_callerWindow
{
@try {
NSLog(@"setValuesToURL was called with params %@ , %@" , strServiceURL , strStorageURL);
self.strDataStorageURL = strStorageURL;
self.strServerURL = strServiceURL;
self.callerWindow = _callerWindow;
[textServerURL setStringValue:[self strServerURL]];
[textDataStorageURL setStringValue:[self strDataStorageURL] ];
NSLog(@" after assigmnemnt %@ , %@" , [self strDataStorageURL], [self strServerURL]);
}
@catch (NSException * e) {
NSLog(@"exception inf0 %@ " ,[[ e userInfo] descriptionInStringsFileFormat]);
}
@finally {
}
}
好消息 - 现在字符串值已分配给NSTextField对象。我在"子"窗口上有一个按钮,单击我正在尝试回调父指针窗口 methid :
- (IBAction) saveConfigurationSetings: (id) sender
{
NSLog(@"saveConfigurationSetings: (id) sender");
//close window and pass back URL strings
self.strServerURL = [textServerURL stringValue];
self.strDataStorageURL = [textDataStorageURL stringValue];
[self.callerWindow passMeBackData: [textServerURL stringValue] strStorageURLParam: [textDataStorageURL stringValue]];
[self close];
}
这里callerWindow变量为空,传递MeBackData失败。这是 h 中的声明:
@interface ConfigurationWindowController : NSWindowController {
...
AppletAppDelegate *callerWindow;
...
}
@property (assign) AppletAppDelegate * callerWindow;
在 M 文件中
@synthesize callerWindow;
你的方法的问题不在于如何做到这一点;相反,你是如何设置你的设置。
对于 Objective-C/Cocoa 来说,更合适的流程可能是执行以下操作:
-
将
ConfigurationWindowController
添加到 MainMenu.xib;将其连接到菜单项 ApplicationMenu> Preferences(如果没记错的话,这应该可以通过实现- (IBAction)openPreferences:(id)sender
或类似的东西来实现。 -
让用户更改设置,并随时将其写入
NSUserDefaults
。可能不需要模式窗口或应用/取消/确定按钮,除非您的设置非常复杂或更改它们非常昂贵(计算)。 -
每当更改设置或窗口关闭时,都会触发相关方可以观察的应用程序
NSNotificationCenter
通知。注意:并非所有设置都需要触发通知;仅那些影响缓存设置值的正在进行的进程。
还有其他方法,但这可能是最容易扩展的方法。
如果问题是在特定窗格上打开设置窗口;设置正确打开窗口的每个控件或菜单项的标记值;并使用 [sender tag]
检查应打开的窗格。
如果问题是应用程序中每个进程都有一个非常具体的设置窗口,那可能是一件坏事™。