为UITableViewController子类重写哪些初始化程序

时间:2009-04-13 04:04:16

标签: iphone objective-c cocoa-touch designated-initializer

我有一个UITableViewController子类,它根据它的使用位置,在NIB中或通过代码进行实例化。在这两种情况下,我都想在初始化方法中进行自定义。这是否意味着我需要实现initWithNibName:bundle: initWithCoder:,并且每个方法都会调用其各自的超级初始值设定项吗?

虽然我现在不需要这个,但如果我还希望能够使用initWithStyle:实例化视图控制器呢?那么我是否需要3种不同的init方法来复制相同的行为?

这似乎违反了整个指定的初始化程序约定,因为基本上有3个单独的初始化程序不会最终调用公共init方法。或者有没有办法在支持3种不同的实例化路由时创建一个公共的指定初始化器?

5 个答案:

答案 0 :(得分:11)

我的困惑是基于错误的信念,即每个班级应该有一个指定的初始化者。这不是真的,在UITableViewController的情况下,有3个指定的初始化器(据我所知):

  1. initWithStyle:在当地宣布
  2. initWithNibName:bundle:继承自UIViewController
  3. initWithCoder:采用NSCoding协议
  4. 您需要在子类中覆盖1 或更多 ,具体取决于您的子类如何实例化。在我的情况下,我必须实现#2和#3,因为类可以从NIB加载,或者通过代码参考NIB实例化。 (我想你很少会将initWithStyle:initWithNibName:bundle:同时用于一个班级。)

    我发现Apple的 Coding Guidelines for Cocoa 很有帮助。

答案 1 :(得分:7)

内部,

  • UITableViewController的-initWithStyle:调用超级-init,然后设置_tableViewStyle ivar。
  • UIViewController的-init只是使用默认参数调用-initWithNibName:bundle:
  • UITableViewController 覆盖-initWithNibName:bundle:

因此,如果您覆盖-initWithNibName:bundle:,则-initWithStyle:也将采用此更改。当然,为了安全起见(因为你不应该依赖于实现细节),请覆盖它们。

(除非您取消/归档实例,否则无需覆盖-initWithCoder:。)

答案 2 :(得分:2)

为了澄清,initWithStyle:UITableViewController仅在文档中发布的初始值设定项,它是一个明确指定的初始值设定项。

initWithNibName:bundle:继承自UIViewController,是该类的指定初始值设定项。因此,根据Cocoa指南,UITableViewController 必须覆盖此方法(通过实施)。但是,这不会使其成为UITableViewController的指定初始化程序。

正如您所指出的,

initWithCoder:是来自NSCoding的隐式指定初始值设定项。

答案 3 :(得分:0)

实施:

- (void) viewDidLoad

并在那里进行组件初始化。

它的优点是只在实际请求视图时进行初始化。

或者只是让所有初始化程序调用一个单独的设置方法。

答案 4 :(得分:0)

对上述帖子的补充-initWithCoder:

如果添加了通过界面构建​​器将视图控制器添加到其父级(例如:如果视图控制器连接到界面构建器中的选项卡栏控制器),则需要覆盖-initWithCoder。

( - 只有在以编程方式创建视图控制器时才会调用initWithNibName。)