Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在NSWindow中显示不同NSViewController的正确方法_Objective C_Macos_Cocoa_Appdelegate_Nsviewcontroller - Fatal编程技术网

Objective c 在NSWindow中显示不同NSViewController的正确方法

Objective c 在NSWindow中显示不同NSViewController的正确方法,objective-c,macos,cocoa,appdelegate,nsviewcontroller,Objective C,Macos,Cocoa,Appdelegate,Nsviewcontroller,我正在开发一个应用程序,它是一个单一的NSWindow,单击窗口内的按钮将显示一个NSViewController,该控制器中存在一个按钮,该按钮将显示一个不同的NSViewController。我知道如何交换窗口中的视图,但在尝试使用多个视图控制器时遇到了一个问题。我已经解决了这个问题,但我认为我没有以适当的方式完成这个行为 我最初在AppDelegate中定义了一个方法: - (void)displayViewcontroller:(NSViewController *)viewContro

我正在开发一个应用程序,它是一个单一的
NSWindow
,单击窗口内的按钮将显示一个
NSViewController
,该控制器中存在一个按钮,该按钮将显示一个不同的
NSViewController
。我知道如何交换窗口中的视图,但在尝试使用多个视图控制器时遇到了一个问题。我已经解决了这个问题,但我认为我没有以适当的方式完成这个行为

我最初在
AppDelegate
中定义了一个方法:

- (void)displayViewcontroller:(NSViewController *)viewController {
    BOOL ended = [self.window makeFirstResponder:self.window];
    if (!ended) {
        NSBeep();
        return;
    }
    [self.box setContentView:viewController.view];
}
我为AppDelegate的
NSButton
设置了一个目标/操作,在这里我调用该方法来显示一个新的视图控制器:

- (IBAction)didTapContinue:(NSButton *)sender {
    NewViewController *newVC = [[NewViewController alloc] init];
    [self displayViewcontroller:newVC];
}
这确实有效-它显示新视图控制器的视图。但是,如果我单击该视图中的任何按钮,该按钮的目标/操作设置位于其视图控制器类中,则应用程序会立即崩溃

要解决此问题,我必须将
didTapContinue:
更改为以下内容:

- (IBAction)didTapContinue:(NSButton *)sender {
    NewViewController *newVC = [[NewViewController alloc] init];
    [self.viewControllers addObject:newVC];
    [self displayViewcontroller:[self.viewControllers lastObject]];
}
首先,你能解释一下为什么这能解决问题吗?似乎与控制器在内存中“保持”的方式有关,但我不确定


我的问题是,如何设置它,以便可以从任何视图控制器中交换视图?我计划获取对AppDelegate的引用,并使用我刚刚在该类中实例化的新控制器调用
displayViewcontroller:
,但这会导致崩溃。我需要首先将其存储在数组中,然后将该引用发送到方法中。这是一种有效的方法吗?将
viewControllers
数组公开,然后使用
lastObject
调用该方法,或者应该如何设置该方法?

代码中有趣的是,每次调用iAction时,您都会分配/初始化一个新的视图控制器。每次调用iAction方法时,您的视图可能都是全新的,但我认为您想要显示的视图数量有限。就我所知,这使得你的观点只有在你的IBAction方法很长的时候才会存在。视图仍然存在,是因为您尚未刷新它。但是,在堆中不再存在的视图控制器内调用方法(因为您离开了iAction方法,并且所有本地对象(例如视图控制器)都从堆中取出,而不是从ARC中取出)会导致应用程序崩溃,因为您引用的内存空间不在使用中或被其他对象使用

当您将视图添加到ViewController阵列时,为什么应用程序可以工作?我假设此数组是在AppDelegate中启动的数组,现在您将具有强引用计数的视图控制器添加到ViewController数组中。离开iAction方法时,视图控制器仍具有强引用,ARC不会取消分配视图控制器

这是正确的方法吗?嗯,这很有效。我不认为这是一个很好的编程,因为在一个方法中,如果一个对象在离开该方法后需要保持活动状态,那么就不需要在该方法中alloc/init该对象。最好在AppDelegate的init、awakeFromNIB或windowDidLoad方法中的某个位置分配和初始化视图控制器。当前解决方案的问题是,您正在创建一个无休止的视图控制器阵列,其中只使用最后一个。在某个地方,您的程序将感受到这个非常长的相当重的对象数组(视图控制器)的负担,并将耗尽内存

希望这有帮助

顺便说一下,这与你是使用小牛还是约塞米蒂无关。我在想一个故事板解决方案,但这不能回答你的问题

亲切问候,,
MacUserT

快速提问。你是在Mavericks还是Yosimite工作?@MacUserT Yosemite:)