WindowControllers,IBOutlets和面向对象的编程?

时间:2013-09-30 03:03:25

标签: objective-c cocoa class nswindowcontroller

我为主题缺乏特异性而道歉,但我不完全确定如何对我的问题进行分类。这是一个很高级别的问题,但我觉得好像人们必须一直遇到这个问题,我想知道他们是如何处理这个问题的。我是客观c和面向对象编程的相对noob,所以请原谅我,如果这对你很多是显而易见的。

到此为止。我有一个cocoa应用程序,它在mainMenu.xib中创建主窗口和主应用程序控制器。我的myMainAppController对象包含另一个windowController,比如mySubWindowController,它是从它自己独立的nib文件启动的,如下所示。让我们说subWindow有两个元素,可能是NSTextfield和NSButton。所以......

myMainAppController.h
@interface
   @property (strong) MySubWindowContorller *mySubWindowController;
   ........ so forth


MyMainAppController.m
@implementation
 ......
 self.mySubWindowController = [MySubWindowController alloc] initWithWindowNibName:
 @"mySubWindow"];  
 etc...


MySubWindowController.h
@ interface
  IBOutlet (weak) NSTextfield *myTextField;
  IBOutlet (weak) NSButton *myButton;
....

到目前为止,我认为这么好。非常标准的东西,对吗?所以这是我的问题的症结所在。在我的类的这个结构下,如何将subWindow中的任何信息或活动返回到我的mainAppController以及从mainAppController到subWindow的数据?我似乎无法将文本域/按钮中的IBOutlet或IBAction返回到myMainAppController.h,所以除了使用KVO之外,myMainAppController将如何从mySubWindowController获取任何信息?如果在subWindow中实现了需要myMainWindowController元素的动作怎么办?我无法将操作消息发送回myMainAppController,mySubWindowController无法访问其包含类的其他元素。我想我可以在myMainAppController中向mySubWindowController声明和定义所需元素的软指针,但这似乎违反了“面向对象”和本地化。

当主窗口和子窗口需要协调数据和逻辑时,你在这种情况下做什么?由于我的经验不足,我是否遗漏了一些完全明显的东西,或者这种情况是否相当普遍?在我使用我的应用程序的相对较短的时间内,我已经遇到过这几次了。试图了解别人如何处理这个......

提前感谢任何想法。

2 个答案:

答案 0 :(得分:0)

为此,您必须编写自己的自定义代理。希望下面的代码可以帮助你。在这里有两个窗口控制器,让我们说AwindowController和BwindowController。如果在AwindowController上发生任何活动,那么BwindowController就会知道。例如,我在AwindowController中创建了一个按钮,如果我们按下该按钮,那么BwindowController将获得一些按钮点击AwindowController的消息或数据。就像那样,您可以发送任何数据或字符串值,无论您要发送哪个。 注意: - 客户代表已用BWindowController

编写
#import "sampleDelegate.h"
#import <Cocoa/Cocoa.h>
#import "BWindowController.h"

@interface AWindowController : NSWindowController<sampleDelegate>

{
    NSString *text;
}
@property(readwrite,retain)NSString *text;
-(IBAction)doSet:(id)sender;

@end

#import "AWindowController.h"
#import "BWindowController.h"

@interface AWindowController ()

@end

@implementation AWindowController
@synthesize text;


- (id)initWithWindow:(NSWindow *)window
{
    self = [super initWithWindow:window];
    if (self) {
        // Initialization code here.
    }

    return self;
}

-(NSString*)getDataValue
{
    return @"Button clicked on AWindow";
}

- (void)windowDidLoad
{
    [super windowDidLoad];

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}

-(NSString*)windowNibName
{
    return @"AWindowController";
}

-(IBAction)doSet:(id)sender
{
    [self setText:[self text]];
    BWindowController *b=[[BWindowController alloc]init];
    b.delegate=self;
    [b showWindow:self];
}
@end

#import <Cocoa/Cocoa.h>
#import "sampleDelegate.h"

@protocol sampleDelegate <NSObject>
@required
-(NSString *)getDataValue;
@end
@interface BWindowController : NSWindowController<sampleDelegate>
{
    NSString *bTextValue;
    id<sampleDelegate>delegate;
}
@property(readwrite,retain)NSString *bTextValue;
@property(readwrite,assign)id<sampleDelegate>delegate;
@end

#import "BWindowController.h"
@interface BWindowController ()

@end

@implementation BWindowController
@synthesize bTextValue,delegate;
- (id)initWithWindow:(NSWindow *)window
{
    self = [super initWithWindow:window];
    if (self) {
        // Initialization code here.
    }

    return self;
}
-(NSString *)getDataValue
{
    return nil;
}
- (void)windowDidLoad
{
   NSString *str= [[self delegate]getDataValue];
    [self setBTextValue:str];
    [super windowDidLoad];

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}

-(NSString*)windowNibName
{
    return @"BWindowController";
}
@end

答案 1 :(得分:0)

如果只有一个mainAppController,则应使用单例模式。创建一个方法+ getSingleton()以从任何地方访问单例实例。 NSApplication也使用单例模式,请参阅+ sharedApplication()。

可以在此处找到objective-c上下文中单例模式的讨论:https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/Singleton.html

如果由于某种原因你无法使用单例模式,则需要从窗口返回到mainAppController的链接。要实现此目的,请取消选中IB中的选项以自动实例化子窗口。相反,在mainAppController中实现awakeFromNib并自己实例化子窗口,并将指针传递给mainAppController。