在 viewDidLoad 之前调用 ViewController 上的自定义 init 方法
Posted
技术标签:
【中文标题】在 viewDidLoad 之前调用 ViewController 上的自定义 init 方法【英文标题】:Custom init method on ViewController to be called before viewDidLoad 【发布时间】:2013-06-28 13:33:10 【问题描述】:我有一个自定义容器视图控制器,我从情节提要中实例化它,它有一堆方法可以修改我已经设置出口到情节提要的子视图的内容。
有很多方法可以实例化这个 ViewController,目前我必须确保,无论我如何实例化它,我要么显示它,显式调用 loadView
,要么访问它的 .view
属性我开始做任何使用其插座的事情(因为在调用loadView
之前它们都是空指针)。
理想情况下,我想在我的ViewController
的单个初始化方法中调用loadView
或.view
来解决这个问题,而不是必须调用.view
我从中初始化 ViewController 的一堆不同的地方。
UIViewController
类是否有指定的初始化程序?如果没有,我需要用我的自定义初始化逻辑修改哪些方法,以确保无论如何都会在我的 ViewController 初始化时调用它?
【问题讨论】:
UIViewController 文档明确指出永远不应该直接调用loadView
。
@MartinR 是的,Xcode 的警告也明确指出,属性 getter 不应该用于副作用。尽管如此,如果您想在显示 ViewController 并导致 loadView
被调用之前通过插座进行子视图操作,您别无选择,只能使用这两种禁止的方法之一——除非我错过了另一种选择,在哪种情况请在此处提供:***.com/a/1935566/1709587
【参考方案1】:
awakeFromNib
似乎适合您的目的。来自文档:
在实例化过程中,存档中的每个对象都是 未归档,然后使用适合其类型的方法进行初始化。 符合
NSCoding
协议的对象(包括所有UIView
和UIViewController
) 的子类使用它们的初始化initWithCoder:
方法。 ... 毕竟对象 已经实例化和初始化,nib加载代码 为所有这些重新建立出口和操作连接 对象。然后调用对象的awakeFromNib
方法。
【讨论】:
这里值得注意的是,在引用文档中所做的保证,即在调用awakeFromNib
时设置出口变量,在 ViewController
从情节提要加载的情况下,而不是.nib
。见***.com/questions/17400547/… 和***.com/questions/2723042/…【参考方案2】:
您可以覆盖这些以覆盖初始化情况:
- (id) initWithCoder:(NSCoder *)aDecoder
self = [super initWithCoder:aDecoder];
if(self)
[self customInit];
return self;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
[self customInit];
return self;
- (id)init
self = [super init];
if (self)
[self customInit];
return self;
- (void) customInit
//custom init code
但这不是一个好的做法,您应该在 viewDidLoad 中进行子视图操作。
【讨论】:
谢谢。实际上,我自己只是想通了这一点-在询问之前我可能应该做更多的研究-但是:1)我不打算在初始化程序中进行任何子视图操作;正如我解释的那样,我只想调用[self loadView]
以便加载子视图并且出口不为空。 2) 看来,当通过[Storyboard instantiateViewControllerWithIdentifier]
实例化 ViewController 时,在 initWithCoder
中调用 [self loadView]
会引发 NSInternalInconsistencyException。 -1,因为这不能处理我要求的用例。
@MarkAmery:这里真的有必要投反对票吗?您询问了指定的初始化程序并得到了答案。您不能期望foggzilla 创建一个测试项目来检查[self loadView]
是否在initWithCoder
中工作。 - 实际上,我现在犹豫是否要给出替代答案,因为如果它在您的用例中不起作用,您会否决它...
@MartinR 我在问题中提供了用例。我当然认为foggzilla 无法预测我在尝试使用initWithCoder
时遇到的问题,如果我处于他的位置,我可能会给出与他完全相同的答案——我很感激他帮助。尽管如此,这不是目前所说的问题的正确答案,所以我必须 -1。
谢谢@MartinR,你永远不知道你什么时候会踩到蛋壳来回答
@foggzilla:您已经回答了他的主要问题“UIViewController 类是否有指定的初始化程序?”,所以我认为 “谢谢,您的回答是正确的,但事实证明这对我的情况没有帮助”就足够了。 - 但是没有人可以做...以上是关于在 viewDidLoad 之前调用 ViewController 上的自定义 init 方法的主要内容,如果未能解决你的问题,请参考以下文章
在 didSelectRowAtIndexPath 之前调用 viewDidLoad
在 applicationDidFinishLaunching 之前调用 viewDidLoad
在 init 方法完成之前调用 UIViewController viewDidLoad
是否有任何情况可以导致在 didBecomeActive 之前调用 ViewDidLoad?