Iphone UIViewController(init和initWithNibName)

Iphone UIViewController(init和initWithNibName),iphone,cocoa-touch,Iphone,Cocoa Touch,希望进一步了解init和initWithNibName之间的实际区别。因此,这样的答案表明,最好通过“init”间接调用“initWithNibName” 是否有任何情况需要定义“init”和 “initWithNibName”有什么不同 是否有可能需要多次加载任何Nib文件 在单个程序执行期间 问题1和2是否相互关联 第一项问题的答覆 理想情况下,每个initWithNibName在内部调用init,因此在正常情况下不需要同时定义这两个,但如果视图也从loadView加载,则在一种情况下可以从

希望进一步了解
init
initWithNibName
之间的实际区别。因此,这样的答案表明,最好通过“
init
”间接调用“
initWithNibName

  • 是否有任何情况需要定义“init”和 “initWithNibName”有什么不同
  • 是否有可能需要多次加载任何Nib文件 在单个程序执行期间
  • 问题1和2是否相互关联

  • 第一项问题的答覆

    理想情况下,每个
    initWithNibName
    在内部调用
    init
    ,因此在正常情况下不需要同时定义这两个,但如果视图也从
    loadView
    加载,则在一种情况下可以从不同的视图从Nib加载,在另一种情况下也可以从Nib加载

    第二项问题的答覆

    每次在堆栈中推送视图时,都会加载Nib

    第三项问题的答覆

    通过init间接调用
    initWithNibName:
    并不更好。您只需要在某个时候调用
    initWithNibName:
    。您可以在外部或内部执行此操作。有些人认为最好在内部进行。实际上,我有一个名为“LayoutUtil”的类,我保留了与布局相关的助手方法,以避免反复编写与布局相关的繁琐代码。以下是我加载UIViewController的代码:

    + (id)loadController:(Class)classType {
        NSString *className = NSStringFromClass(classType);
        UIViewController *controller = [[classType alloc] initWithNibName:className bundle:nil];
        return controller;
    }
    
    然后我可以做:

    MyViewController *c = [LayoutUtil loadController:[MyViewController class]];
    
    如果需要,可以将一个名为ughhh的方法添加到类中并在其中调用它,这一点都不重要。关键是,在init方法中调用initWithNibName并不是一种更好的做法,但是,您只需要确保在启动UIViewController时在某个点调用它

    - (id)ughhhh
    {
       self = [super initWithNibName:@"Myview" bundle:nil];
       if (self != nil)
       {
       }
       return self;
    }
    
    nib文件肯定需要多次加载。每次在UIViewController上调用initWithNibName时,都必须加载xib。很多人加载UIViewController不拥有的UIView,如下所示:

    [[NSBundle mainBundle] loadNibNamed:@"nameOfXIBFile" owner:self options:nil];
    
    每次调用此函数时,都将加载nib

    在某些情况下,可以缓存nib。UITableView就是一个例子——但表视图实现了它自己的缓存。操作系统没有自动执行任何缓存


    init
    initWithNibName:
    是相关的,因为
    initWithNibName:
    自动调用对象上的init。

    通过“init”间接调用“initWithNibName”并不“更好”。你应该用哪个更适合你的需要。说
    [[UIViewController alloc]init]
    与说
    [[UIViewController alloc]initWithNibName:nil bundle:nil]
    完全一样,因此如果这些是您想要传递的参数,您最好使用
    [[UIViewController alloc]init]

    回答你的问题:

  • 如果需要,可以以不同的方式定义
    init
    initWithNibName:bundle:
    。您可以只定义其中一个。例如,
    UIImagePickerController
    仅定义
    init
    ,如果尝试用nibName:bundle:发送
    init,它将无法正常工作。或者您可以定义一些完全不同的
    init…
    方法。例如,
    UINavigationController
    仅定义
    initWithRootViewController:
    。无论您定义什么init方法,最终都必须调用其超类的init方法之一

  • 是的,可以多次加载nib。如果创建同一视图控制器子类的多个实例,很可能会多次加载同一nib。事实上,视图控制器的单个实例可以多次加载其nib。怎么用?如果视图控制器的视图当前不在屏幕上,并且系统内存不足,系统将要求视图控制器释放其视图。如果视图控制器以后需要将其视图放回屏幕,它将再次加载nib

  • 问题1和2不相关


  • 请注意:要分配给self,您需要有一个以
    init
    开头的方法。因此,
    -(id)initughhh
    不知何故,我在文档中找不到
    init()
    (无参数)(仅
    init(nibName:bundle:)
    init(coder:)
    ),但我已经确认,初始化没有参数的UIViewController子类最终会执行
    init(nibName:nil,bundle:nil)
    。我看到很多博客帖子建议您添加一个方便的初始化器
    init()
    ,它确实可以做到这一点,但似乎没有必要/已经处理好了。。。?