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

时间:2012-05-31 13:51:08

标签: cocoa xib init nsviewcontroller

我正在编写一个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不应该是init两次,但我需要在IB中显示正确的xib文件。

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

1 个答案:

答案 0 :(得分:1)

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

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

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