initWithNibName 要么调用两次,要么加载错误的 xib



我正在编写一个Cocoa应用程序,并希望该应用程序像一种向导一样工作。 因此,在主窗口中,我有一个自定义视图,该视图与用户交互,并在用户逐步完成向导阶段时从登录更改为设备激活屏幕。 我目前已经覆盖了WizardViewController的awakeFromNib方法:

- (void)awakeFromNib{
   //If no redirect request save, add first view: ID Login
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   NSString *tokenRequest = [defaults objectForKey:@"redirectRequestToken"];
   if (!tokenRequest){
       SignInWithIDViewController *signInViewController = [[SignInWithIDViewController alloc] initWithNibName:@"SignInWithIDViewController" bundle:nil];
       [wizardView addSubview:[signInViewController view]];
   } else {
    NSLog(@"Have already logged in.");
   }
}

照原样,SignInIDViewController 中的 initWithNibName 被调用两次,一次由我显式调用,另一次是在加载视图时(大概是通过 loadView)。 但是,如果我只是调用init,那么initWithNib名称只被调用一次,但加载了错误的xib文件(DeviceActivationViewController 类)。 我似乎无法弄清楚我做错了什么,因为 signInViewController 不应该初始化两次,但我需要在 IB 中显示正确的 xib 文件。

我目前在此类中唯一不是用户界面 IBAction 的其他方法是生成的 initWithNibName 方法以及添加的 NSLog 语句。

我认为在 IB(蓝色立方体)中创建对象并在代码中实例化它们是问题所在。 如果你在 IB 中为它们创建了对象,那么它们将在 awakeFromNib 中实例化,你也不应该在代码中对它们调用 alloc init ——这将创建一个新实例。

我在OSX中使用视图控制器的经验并不多,但似乎您无法将IBActions连接到视图控制器(作为文件的所有者)。 我让它工作的方法是对自定义视图(添加视图控制器时为您创建的)进行子类化,将该视图的类更改为新的子类,并将操作方法放在该类中。似乎这应该由视图控制器处理,但我认为它不起作用与视图控制器不在 OSX 中的响应器链中有关(而我认为它在 iOS 中)。

编辑后:在绕道进入内存管理问题之后,我想我找到了最好的方法。 您可以并且可能应该(以符合Apple的MVC范式)将按钮方法放在视图控制器类中,而不是像我上面所说的那样放在视图中。 实际上,您可以将 IBActions 连接到视图控制器(作为文件的所有者),您只需确保在代码中实例化视图控制器时保留视图控制器即可。 为此,您需要使 signInViewController 成为实例化 SignInViewController 类的任何类中的属性,并在属性声明中使用"保留"。 然后,您不需要(也不应该)在IB中创建任何蓝色立方体。

最新更新