initWithNibName调用两次或错误的xib加载 [英] initWithNibName either called twice or wrong xib loaded

查看:145
本文介绍了initWithNibName调用两次或错误的xib加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

   - (void)awakeFromNib {
//如果没有重定向请求保存,添加第一个视图:ID登录
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSString * tokenRequest = [defaults objectForKey:@redirectRequestToken];
if(!tokenRequest){
SignInWithIDViewController * signInViewController = [[SignInWithIDViewController alloc] initWithNibName:@SignInWithIDViewControllerbundle:nil];
[wizardView addSubview:[signInViewController view]];
} else {
NSLog(@已经登录。
}
}


$ b $ p

因此,SignInIDViewController中的initWithNibName被调用两次,显式地由我,并再次当视图加载(可能通过loadView)。但是,如果我只是调用init,那么initWithNib名称只被调用一次,但是加载了错误的xib文件(DeviceActivationViewController类的)。我似乎不知道我做错了什么,因为signInViewController不应该是两次,但我需要在IB中显示正确的xib文件。



解决方案

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

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



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

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


I'm programming a Cocoa application and want the application to work as a kind of Wizard. So in the main window I have a Custom View that interacts with the user and changes from a sign in to a device activation screen as they step through the stages of the wizard. I have currently overridden the WizardViewController's awakeFromNib method:

- (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.");
   }
}

As is, initWithNibName in SignInIDViewController gets called twice, once explicitly by me, and again when the view is loaded (presumably through loadView). However, if I simply call init then initWithNib name is only called once, but the wrong xib file is loaded (of the DeviceActivationViewController class). I can't seem to figure out what I'm doing wrong, because the signInViewController should not be init twice, but I need the proper xib file in IB to display.

The only other method I have in this class currently that is not a user interface IBAction is the generated initWithNibName method plus an added NSLog statement.

解决方案

I think that creating the objects in IB (the blue cubes), and instantiating them in code is the problem. If you've created objects for them in IB, then they will be instantiated in awakeFromNib, you shouldn't also call alloc init on them in code -- that will create a new instance.

I don't have a lot of experience with using view controllers in OSX, but it seems that you can't connect IBActions to the view controller (as file's owner). The way I made it work, was to subclass the custom view (that's created for you when you add a view controller), change the class of that view to your new subclass, and put the action methods in that class. It seems like this should be something that would be handled by the view controller, but I think it not working has something to do with the view controller not being in the responder chain in OSX (whereas I think it is in iOS).

After Edit: After a detour into memory management problems, I think I found the best way to do this. You can, and probably should (to comply with Apple's MVC paradigm) put the button methods in the view controller class rather than in the view as I said above. You actually can connect the IBActions to the view controller (as File's Owner), you just need to make sure that the view controller is retained when you instantiate it in code. To do this, you need to make signInViewController a property in whatever class you're instantiating the SignInViewController class in, and use "retain" in the property declaration. Then you don't need to (and shouldn't) create any of the blue cubes in IB.

这篇关于initWithNibName调用两次或错误的xib加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆