我有一个UITableViewController
子类,它根据它的使用位置,在NIB中或通过代码进行实例化。在这两种情况下,我都想在初始化方法中进行自定义。这是否意味着我需要实现initWithNibName:bundle:
和 initWithCoder:
,并且每个方法都会调用其各自的超级初始值设定项吗?
虽然我现在不需要这个,但如果我还希望能够使用initWithStyle:
实例化视图控制器呢?那么我是否需要3种不同的init方法来复制相同的行为?
这似乎违反了整个指定的初始化程序约定,因为基本上有3个单独的初始化程序不会最终调用公共init方法。或者有没有办法在支持3种不同的实例化路由时创建一个公共的指定初始化器?
答案 0 :(得分:11)
我的困惑是基于错误的信念,即每个班级应该有一个指定的初始化者。这不是真的,在UITableViewController
的情况下,有3个指定的初始化器(据我所知):
initWithStyle:
在当地宣布initWithNibName:bundle:
继承自UIViewController
initWithCoder:
采用NSCoding
协议您需要在子类中覆盖1 或更多 ,具体取决于您的子类如何实例化。在我的情况下,我必须实现#2和#3,因为类可以从NIB加载,或者通过代码参考NIB实例化。 (我想你很少会将initWithStyle:
和initWithNibName:bundle:
同时用于一个班级。)
我发现Apple的 Coding Guidelines for Cocoa 很有帮助。
答案 1 :(得分:7)
内部,
-initWithStyle:
调用超级-init
,然后设置_tableViewStyle
ivar。-init
只是使用默认参数调用-initWithNibName:bundle:
。-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。)