16

我有一个UITableViewController实例化的子类,具体取决于它的使用位置、NIB 或通过代码。在这两种情况下,我都想在初始化方法中进行自定义。这是否意味着我需要同时实现initWithNibName:bundle: and initWithCoder:,并且每个方法都会调用其各自的超级初始化程序?

虽然我现在不需要这个,但如果我也希望能够用 实例化视图控制器initWithStyle:怎么办?然后我需要 3 种不同的 init 方法来复制相同的行为吗?

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

4

5 回答 5

11

我的困惑是基于一个错误的信念,即每个类都应该有一个指定的初始值设定项。这不是真的,如果UITableViewController有 3 个指定的初始化程序(据我所知):

  1. initWithStyle:本地声明
  2. initWithNibName:bundle:继承自UIViewController
  3. initWithCoder:从采用NSCoding协议

根据子类的实例化方式,您需要在子类中覆盖其中的一个或多个。就我而言,我必须实现#2 和#3,因为该类可以从 NIB 加载,或者通过参考 NIB 的代码实例化。(我想你很少会同时使用initWithStyle:一个initWithNibName:bundle:类。)

我发现 Apple 的Cocoa 编码指南很有帮助。

于 2009-04-16T15:14:56.880 回答
7

在内部,

  • UITableViewController-initWithStyle:调用 super 的-init然后设置_tableViewStyleivar。
  • UIViewController-init只需-initWithNibName:bundle:使用默认参数调用。
  • UITableViewController不会覆盖-initWithNibName:bundle:.

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

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

于 2010-02-11T07:35:10.930 回答
2

为了澄清,initWithStyle:作为UITableViewController文档中唯一发布的初始化程序,它是一个明确指定的初始化程序。

initWithNibName:bundle:继承自 UIViewController 并且是该类的指定初始化程序。因此,根据 Cocoa 指南,UITableViewController 必须重写此方法(通过实现它)。但是,这并不能使它成为 的指定初始值设定项UITableViewController

initWithCoder:正如您所指出的,它是来自NSCoding.

于 2010-02-10T18:34:15.553 回答
0

实施:

- (void) viewDidLoad

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

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

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

于 2009-04-13T06:19:52.707 回答
0

对上面提到的帖子的补充——initWithCoder:

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

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

于 2012-01-03T17:48:00.887 回答